ホームページ  >  記事  >  バックエンド開発  >  YII フレームワーク ソース コード分析 (Baidu PHP 専門家によって作成 - オリジナル バージョン - 広告なし、ウォーターマークなし)_PHP チュートリアル

YII フレームワーク ソース コード分析 (Baidu PHP 専門家によって作成 - オリジナル バージョン - 広告なし、ウォーターマークなし)_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:28:33926ブラウズ

YII フレームワークのソースコード分析

百度アライアンス事業部——黄銀峰

カタログ

1. はじめに3

1.1、Yii 入門 3

1.2. この記事の内容と構成3

2. コンポーネント化とモジュール化 4

2.1、フレームワークのロードと実行プロセス 4

2.2、YiiBase静的クラス5

2.3、コンポーネント6

2.4、モジュール9

2.5、アプリアプリケーション10

2.6、WebAppアプリケーション11

3. システムコンポーネント 13

3.1、ログルーティングコンポーネント13

3.2、URL管理コンポーネント15

3.3、例外処理コンポーネント17

3.4、キャッシュコンポーネント17

3.5、Angular アクセス制御コンポーネント 19

3.6、グローバルステートコンポーネント21

4. コントローラー層 23

4.1、アクション23

4.2、フィルター24

4.3、アクションとフィルターの実行処理26

4.4、アクセス制御フィルター27

5.モデルレイヤー30

5.1、DAOレイヤー30

5.1.1、データベース接続コンポーネント30

5.1.2、トランザクションオブジェクト31

5.1.3、コマンドオブジェクト31

5.2、メタデータとコマンドコンストラクター32

5.2.1、テーブル構造クエリ32

5.2.2. クエリ条件オブジェクト33

5.2.1、コマンドコンストラクター33

5.3、ORM(アクティブレコード) 34

5.3.1、テーブルメタデータ情報34

5.3.2、単一テーブル ORM 34

5.3.3、マルチテーブルORM 36

5.3.4、CModelおよびCValidator 37

6. レイヤー 38 を表示します

6.1、ビューレンダリングプロセス38

6.2、ウィジェット39

6.3、クライアントスクリプトコンポーネント40

1. はじめに

1.1、Yii の概要

Yii の作者は中国系アメリカ人の「Xue Qiang」で、元々は Prado の中核開発メンバーの 1 人でした。 2008 年、Xue Qiang は新たに Yii フレームワークを開発し、2008 年 12 月 3 日に Yii1.0 バージョンをリリースしました。

Yii は現在、最も優れた PHP フレームワークの 1 つであり、サポートされている機能には、MVC、DAO/ActiveRecord、I18N/L10N、キャッシュ、AJAX サポート、ユーザー認証とロールベースのアクセス制御、スキャフォールディング、入力検証、デプロイ コンポーネントが含まれます。イベント、テーマ、Web サービスなど。

Yii のアイデアの多くは他の優れた Web フレームワークを参照しています (私たちも何かを書くときに他の人のアイデアを参照したいですか? 何かありますか? ふふ、私たちは皆、他人の肩の上に立って仕事をするのが好きです!)。短いリスト 1 つ:

フレーム名

参考アイデア

プラド

コンポーネントおよびイベント駆動型プログラミングモデルに基づく、データベース抽象化

レイヤー、モジュラーアプリケーションアーキテクチャ、国際化とローカリゼーションなど

Ruby on Rails

構成のアイデア、アクティブレコードに基づくORM

jQuery

統合されたjQuery

シンフォニー

フィルターの設計とプラグインのアーキテクチャ

ジョームラ

モジュラー設計と情報翻訳ソリューション

1.2. この記事の内容と構成

この記事では、Yii1.1.8 バージョンのソースコードを詳細に分析します。この記事の内容と構成は次のとおりです: コンポーネント化とモジュール化: コンポーネントおよびイベント駆動型プログラミング モデルに基づいて Yii の基本クラス (CComponent) を分類します。

分析; コンポーネント化とモジュール化の動作原理を分析する; WebApp アプリケーション作成コントローラーのプロセスなどを分析する。

システムコンポーネント: Yii フレームワークに付属する重要なコンポーネントを分析します。主に、ログルーティングコンポーネント、URL 管理コンポーネント、例外処理コンポーネント、キャッシュコンポーネント、ロールベースのアクセス制御コンポーネントなどが含まれます。

コントローラー層: コントローラーには主にアクションとフィルターが含まれており、アクションとフィルターの動作原理を分析します。モデル層: DAO層、メタデータ、コマンドコンストラクター、ORMの原理を分析します

ビューレイヤー: ビューレイヤーのレンダリングプロセス、ウィジェット、クライアントスクリプトコンポーネントを分析します

この文書の誤りや不備は避けられないものであり、この文書の読者が私たちを批判し、修正してくれることを心から願っています。

2. コンポーネント化とモジュール化

2.1、フレームワークのロードと実行プロセス

スタート

YiiBase.phpをロードする 1. autoloadメソッドをインストールしてクラスのインスタンス化の準備をする 2. フレームワーク内のすべてのクラスのパスを取得する(Yii1.1.8では合計208クラス)

ActionIdに基づいてActionオブジェクトを作成 1.メンバー関数からアクションを検索 2.ActionMapからアクションを検索

投げる

リクエストコンポーネントのロード

(取得、投稿、Cookie)

アクションの作成 いいえ 成功しましたか? 頻繁に

WebApp インスタンスを作成する 1. エイリアスを初期化します: application、webroot、ext 2. 例外処理ハンドルをインストールし、例外がスローされたときに例外処理コンポーネントに引き渡します 3. コア コンポーネントを構成します: urlManager、errorHandler、session 、dbなど。 4. 構成に従って、コンポーネント、サブモジュール、WebAppメンバー属性などを構成するための情報。 5. プリロードコンポーネントをロードします: ログコンポーネント、リクエストコンポーネントなど

WebAppを実行する

1. onBeginRequest イベントをトリガーします

URL管理コンポーネントをロードし、構成情報に従ってURLを分析し、ルートを解析します:route=ControllerId/ActionId

ControllerIdに基づいてコントローラーを作成 1.ControllerMapから検索 2.サブモジュールから検索 3.ControllerPathから検索

コントローラーを作成して正常にスローできましたか?違いはありません

よく

filters() 設定に従って現在のアクションのすべてのフィルター オブジェクトを作成します

Filter1 の preFilter メソッドを実行します Filter2 の preFilter メソッドを実行します

GetパラメータがActionパラメータと異なっていないか、正常であるかを確認してください

一貫性のある

アクションを実行

部分レンダリング

HTMLのコア部分をレンダリングします

レイアウトレンダリング

HTML全体をレンダリングします

クライアントスクリプトレンダリングにはJavaScriptとCSSが埋め込まれ、最終的なHTMLを生成します

HTMLをエコー

2. リクエストを処理します

コントローラーを実行

Filter2のpostFilterメソッドを実行する Filter1のpostFilterメソッドを実行する

3. onEndRequest イベントをトリガーします

登録ハンドル:

例外処理コンポーネント

XX で例外がスローされました

例外をスローします。 。 。

終了

例えば、ログを取る

Yii フレームワークのロードと実行のプロセスは 4 つの段階に分かれています (少し怖く見えるかもしれませんが、問題はありません。最初に大まかなアイデアを知りましょう):

ステップ1: WebAppの初期化と操作

1.1. YiiBase.php をロードし、ユーザーの設定ファイルをロードします。

1.2. WebApp アプリケーションを作成し、アプリを初期化し、いくつかのコンポーネントをロードし、最後に WebApp を実行します

ステップ2: コントローラーの初期化と操作

2.1. リクエストコンポーネントをロードし、URL管理コンポーネントをロードし、ルーティング情報を取得しますroute=ControllerId/ActionId 2.2. コントローラーインスタンスを作成し、コントローラーを実行します

ステップ3: コントローラーの初期化と操作

3.1. ルーティングに基づいてアクションを作成します

3.2. 設定に従ってアクションのフィルターを作成します

ステップ4: レンダリング段階

4.1、部分ビューのレンダリングとレイアウトビューのレンダリング

4.2、登録されたJavaScriptとCSSをレンダリングします

2.2、YiiBase静的クラス

YiiBase は、YII フレームワークの操作のための共通の基本機能、つまりエイリアス管理とオブジェクト作成管理を提供します。 php オブジェクトを作成するときは、最初にこのクラスの定義ファイルをインクルードし、次にオブジェクトを新規作成する必要があります。

異なる環境(開発環境/テスト環境/オンライン環境)では、Apacheのウェブルートパスの構成が異なる可能性があるため、このクラスの定義ファイルのフルパスは異なります。Yiiフレームワークはエイリアスを通じてこの問題を解決します。 YiiBase の管理によってこの問題は解決されました。

オブジェクトを作成するとき、対応するクラスの定義をインポートする必要があることがよくあります: include()、include_once()、require()、require_once()、set_include_path()。 Yii は、YiiBase::import() を使用してこの問題を一律に解決します。次の図は、YiiBase が提供する「エイリアス管理とオブジェクト作成管理」の動作原理を示しています。

createComponent を通じてオブジェクトを作成します

1. クラスが存在しない場合は、import を通じてインポートします

new を通じてオブジェクトを作成する

2. 新しいオブジェクト

3. 入力に従ってこのオブジェクトの属性を初期化します

インポート

クラス定義をインポートする

へのパスをインポートします

include_path

オートロード

クラスがエイリアスで始まる場合は、無視管理インターフェースを介してフルパスを取得します

エイリアス管理

getPathOfAliassetPathOfAlias

エイリアスのフルパスを追加します

まずエイリアス管理について見てみましょう。これはフォルダーにエイリアスを与えることです (フォルダーは多くの場合モジュールに対応します)。YII フレームワークでは、このエイリアスを使用してフォルダーの完全なパスを置き換えることができます。たとえば、system です。エイリアスはフレームワーク /home/work/yii/framework のパスを表すため、 system.base.CApplication を使用して

を表すことができます

/home/work/yii/framework/base/CApplication.php ファイル パス。もちろん、アプリケーション層 (私たちの) コードでは、Yii::setPathOfAlias を通じてエイリアスを登録することもできます。

通常、ファイルを参照するには絶対パスまたは相対パスを使用します。もちろん、これら 2 つの状況には欠点があります。絶対パス: コードをテスト環境またはオンライン環境にデプロイする場合、インクルードされるファイルのパスを大量に変更する必要があります。相対パス: 一部のモジュール フォルダーの場所が調整される (名前が変更される) と、すべての相対パスが変更されます。変更する必要があります。エイリアスの使用方法に必要な変更は 1 つだけです。エイリアスの登録時、つまり Yii::setPathOfAlias() です。このようにして、フォルダー内の変更によって生じるコードの変更を 1 か所に集中させることができます。

インポート関数を見てください: a. クラスのオブジェクトを作成できるように、クラスの定義をインポートします。 b. このファイルの下にすべてのファイルを直接含めることができます。 Yii::import は以下と同等です

5つの関数の統合: include()、include_once()、require()、require_once()、set_include_path()。また、一般にこれらの関数よりも速度が速くなります。もちろん、Yii::import はパス変更によるトラブルを解決できるエイリアス機能をサポートしています。

最後に、YII フレームワークでオブジェクトを作成するには 2 つの方法があります。1. new キーワードを使用します。2.

Yii::createComponentメソッドを使用します。

new キーワードを使用してオブジェクトを作成すると、autoload は 3 つのステップで対応するクラスの定義を検索します。 a. それがフレームワーク内のクラスであるかどうかを判断します (フレームワークのすべてのクラスとこのクラスのフルパス)は、YiiBase 変数のメンバーに保存されます。これは、インポートされるフレームワーク全体と同等です); 2. このクラスのインポートに Yii::import が使用されているかどうかを確認します。フレームワーク以外のクラスの場合、この定義をインポートする必要があります。このクラスのオブジェクトを作成するときは、最初にクラスを作成します。 3. include_path ディレクトリからこのクラス名にちなんだ名前の PHP スクリプトを見つけます。このようにして、開発時にファイル名と一致するクラス名を保存するようにしてください。このファイルが含まれるフォルダーなので、これを置く必要はありません。フォルダー内の各ファイルがインポートされます。

Yii::createComponent メソッドを使用してオブジェクトを作成する場合、 new キーワードよりも多くの機能が提供されます: a. このクラスのフルパスエイリアスを通じてクラスの場所とクラス名を指定します (クラス名は一貫している必要があります)ファイル名 ) の場合、このクラスがインポートされていない場合、このクラスの定義はフルパスに従って自動的にインポートされます。 2. 作成されたオブジェクトのメンバー変数に値を割り当てます。つまり、以下の図で説明されているように、以前はコードを書くのに 3 行以上必要でしたが、現在は 1 行のコードで完了できます (書く量が減り、実行できる量が増えます)。

Yii::import('application.models.Student');

$obj = 新入生();

$obj->年齢 = 16;

$obj->name = 'ジェリー';

$obj = Yii::createComponent(array( 'class'=>'application.models.Student', 'age'=>16,

「名前」=>「ジェリー」

));

2.3、コンポーネント

CComponent クラスは、フレームワーク全体のコンポーネント プログラミングとイベント駆動型プログラミングの基礎を提供するコンポーネントです。YII フレームワークのほとんどのクラスは、CComponent クラスを基本クラスとして使用します。 CComponent クラスは、そのサブクラスに 3 つの機能を提供します: 1. メンバー変数の展開

次のような 2 つのメンバー関数 (getXXX/setXXX) を定義してメンバー変数を定義します。

パブリック関数 getText() {…} パブリック関数 setText {…}

これはテキストメンバー変数を定義するのと同等で、次のように呼び出すことができます

$a=新しい CComponent;

$a=$component->text; // $a=$component->getText();

と同等

$component->text='abc' // $component->setText('abc');

と同等

CComponent は、マジックメソッド get および set を通じて「メンバー変数拡張」機能を実装します。クラス自体に存在しないメンバー変数が操作される場合、php はこのクラスの get メソッドおよび set メソッドを呼び出して処理します。 CComponent は、これら 2 つのマジック メソッドを使用して「メンバー変数展開」機能を実装します。次の図は、2 つのメンバー変数 active と sessionName を追加する CComponent のサブクラスを示しています。この図は、これら 2 つのメンバー変数の呼び出しプロセスを示しています。

アクティブになる

アクティブに設定

このメンバー変数は存在しますか?

設定なし()

get()

getSessionName

setSessionName

は、このオブジェクトのメンバー変数を使用します

getXXX setXXX

オブジェクト指向プログラミングでは、メンバー変数を直接定義するだけで十分ですが、なぜ CComponent は 2 つの関数を定義してメンバー変数を実装するのでしょうか?主な理由の 1 つは、メンバー変数の「読み込みを遅らせる」必要があることです。一般に、クラスのメンバー変数はコンストラクターまたは初期化関数で均一に割り当てられますが、Web リクエストの処理中にすべてのメンバー変数が割り当てられるわけではありません。たとえば、App クラスは $cache と $db

という 2 つのメンバー変数を定義します。

($cache はキャッシュ オブジェクト、$db はデータベース リンク オブジェクト)、これら 2 つのオブジェクトは App クラスが初期化されるときに初期化されます

データベース リンク オブジェクトを作成する場合、ただし、コンテンツがキャッシュを通じて取得できる Web ウェブサイトの一部のページでは、データベース リンク オブジェクトを実際に作成する必要はありません。 App を CComponent のサブクラスとして定義する場合は、App クラスに getCache/getDb という 2 つのメソッドを定義します。これにより、db メンバー変数を初めて使用するときに getDb 関数を呼び出してデータベース リンクを初期化できるようになります。遅延読み込み - つまり、最初の使用時に初期化します。遅延読み込みにより関数呼び出しが 1 つ追加されますが、メンバー変数の不必要な初期化を減らすことができ (一般に、実際に Web サイトのアクセス速度が向上します)、コードの保守と拡張が容易になります。

「メンバー変数展開」機能の最も重要な用途は、もちろんこの機能には他の用途もあります。考えてみてください。メンバー変数を操作するときは、実際には getXXX メンバーと setXXX メンバーを呼び出していることになります。関数、コードの一部を呼び出しています。

2. イベントモデル

イベント モデルは、デザイン パターンの「オブザーバー パターン」です。オブジェクトの状態が変化すると、このオブジェクトは他のオブジェクトにイベントを通知できます。

イベント モデルを使用するには、次の 3 つの手順を実装する必要があります: 1. イベントを定義する; 2. イベント ハンドラーを登録する; 3. イベントをトリガーする。

CComponent サブクラスは、on で始まるメンバー関数 (public function onClick(){...} など) を定義してイベントを定義し、attachEventHandler メンバー関数を呼び出してイベント ハンドラーを登録します (複数のイベント ハンドラーを登録できます)。 , 最後に、raiseEvent を呼び出してイベントをトリガーします。

attachEventHandler detachEventHandler raiseEvent

イベントハンドラーコンテナ

クリックしてください

楽しい_11楽しい_12

「楽しい1n

挿入前

fun_2n

挿入後

fun_3n

š

キー

fun_m1

価値

fun_mn

CComponent クラスは、イベントとイベントを処理するためのすべてのハンドルを保存するためにプライベート メンバー変数を使用します。このメンバー変数は、ハッシュ テーブルの名前と値です。ハッシュ テーブルはイベント処理関数です。

3. 行動の束縛

クラスに機能を追加するには 2 つの方法があります: 1. このクラスのコードを直接変更します: いくつかのメンバー関数とメンバー変数を追加します。 2. 派生: サブクラスを通じて拡張します。明らかに 2 番目の方法の方が保守と拡張が簡単です。複数の機能を 1 つのクラスに追加する必要がある場合 (複数のユーザーが異なる時間に)、マルチレベルの派生が必要となり、明らかにメンテナンス コストが増加します。 CComponent は、クラス情報を拡張する特別な方法、つまり動作クラス バインディングを使用します。 Behavior クラスは CBehavior クラスのサブクラスであり、CComponent は 1 つ以上の CBehavior クラスのメンバー関数とメンバー変数を追加できます

自分自身に、不要な場合は特定の CBehavior クラスをアンインストールしてください。簡単な例を次に示します:

//電卓クラス

class Calculator は CBehavior を拡張します

{

パブリック関数 add($x, $y) { return $x + $y; } パブリック関数 sub($x, $y) { return $x - $y;

...

}

$comp = 新しい CComponent();

//私のクラスに電卓機能を追加します

$comp->attachbehavior('電卓', new Calculator());

$comp->add(2, 5);

$comp->sub(2, 5);

CComponent は、get、set、call の 3 つのマジック メソッドを通じて「動作クラス バインディング」機能を実装します。CComponent クラスに存在しないメンバー変数とメンバー メソッドを呼び出す場合、CComponent クラスはこれら 3 つのマジック メソッドを使用して検索します。 「動的にバインドされた動作オブジェクト」について。つまり、存在しないメンバー変数とメンバー メソッドを「動的バインディング オブジェクト」にルーティングします。

attachBehaviorデタッチBehavior

オブジェクトのバインド、バインド解除

obj1

セット()

obj2

存在しません

ノーゲット()

各オブジェクトをクエリする

コール()

obj3

です

このオブジェクトのメンバー変数とメンバー関数を使用します

バインドされたオブジェクト

バインディングオブジェクトの使用プロセス バインディングメンテナンスプロセス

CComponent クラスの特徴を 3 つの文で要約できます:

1. オブジェクトのメンバー変数を設定するときは、実際にコードを実行することになります。

2. オブジェクトの内部状態が変化した場合に、他のオブジェクトに通知できるようにする。

3. オブジェクトをより適切に拡張するには、オブジェクトにメンバー変数とメンバー関数を追加し、オブジェクトのステータスを監視することもできます。

2.4、モジュール

モジュールは、システム全体の中で比較的独立したプログラム単位であり、比較的独立したソフトウェア機能を完成させます。たとえば、Yii に付属する gii モジュールは、オンラインコード生成の機能を実装します。 CModule はすべてのモジュール クラスの基本クラスであり、次の 3 つの部分で構成されます。

a. 基本属性 (モジュール ID、モジュール パスなど); b. モジュールは、これらのコンポーネントのコンテナーと見なされます。モジュールが大きくなると、複数のサブモジュール (それぞれ

) に分割できます。

サブモジュールもこれら 3 つの部分で構成され、再帰的な構造になっています)。次の図は、モジュールとそのメンバー間の包含関係図です:

テンプレートベース

この属性コンポーネントのサブモジュール

次の表に、CModule のさまざまなコンポーネントをリストします。

モジュールのこれら 3 つのコンポーネントを初期化すると非常に便利です。構成には配列を使用します。配列のキーは構成する必要がある属性であり、値は構成する必要がある値です。構成についてはどうでしょうか。 CModule は CComponent クラスを継承しているため、メンバー プロパティを構成するとき、実際にはコードの一部、つまりメンバー関数が実行されます。

配列(

'basePath'=>dirname( FILE ).DIRECTORY_SEPARATOR.'..',//モジュールのパス 'preload'=>array('log'),//ログコンポーネントをプリロードする必要があります

'import'=>array('application.models.*', 'application.components.*',),//インクルードするパス

//コンポーネントの構成

'components'=>array( 'user'=>array(//ユーザーコンポーネントの構成

'allowAutoLogin'=>true

)、

'log'=>array(//ログコンポーネントの構成 'class'=>'CLogRouter',

'routes'=>array(array('class'=>'CWebLogRoute','levels'=>'trace, profile'))

)

)、

//モジュール構成

'モジュール'=>array(

'gii'=>array(//コードモジュール設定を自動生成 'class'=>'system.gii.GiiModule', 'password'=>'123456'

)、

)、

);

2.5、アプリアプリケーション

アプリケーションとは、リクエスト処理における実行コンテキストを指します。その主なタスクは、ユーザーのリクエストを分析し、さらなる処理のために適切なコントローラーにリクエストをディスパッチすることです。また、アプリケーション レベルの構成を維持するサービス センターとしても機能します。このため、アプリケーションは「フロントエンド コントローラー」とも呼ばれます。

Yii は、CApplication クラスを使用して、CModule を継承します。1. run メソッドを追加しました。2. いくつかのコンポーネントを追加しました。

run メソッドは、C 言語の main 関数に相当します。これは、プログラム全体が実行を開始するためのエントリ ポイントです。CApplication には、CWebApplication と CConsoleApplication という 2 つのサブクラスがあります。そのうち、このメソッドを実装します。 onBeginRequest イベントと onEndRequest イベントは、各リクエストの処理の開始時と終了時に開始され、リッスンしているオブザーバーに通知されます。 「Yii フレームワークのロードと実行プロセス」図を確認すると、プロセス全体におけるこのメソッドの役割がわかります。

追加されたメンバー変数、メンバー関数、およびコンポーネントを以下の表に示します。

3パート

メンバー詳細

手順

基本属性

(ユーザーはモジュール全体のグローバルなものを設定します)

ID

モジュールID

親モジュール

親モジュール

ベースパス

現在のモジュールのパス

モジュールパス

サブモジュールのパス

パラメータ

モジュールのパラメータ

プリロード

プリロードされたコンポーネントIDが必要です

行動

バインドされた動作クラス

エイリアス

新しく追加されたエイリアスはYiiBaseのエイリアス管理に追加されます

インポート

含めるファイルまたはパス

コンポーネント

(これはモジュールのコアコンポーネントです)

コンポーネント

配列型、配列の各メンバーはコンポーネントを記述します

サブモジュール

(これによりモジュールに拡張性が提供されます)

モジュール

配列型。配列の各メンバーはモジュールを記述します。

各モジュールもこれら 3 つの部分で構成されており、再帰的な構造になっています

カテゴリー

名前

手順

メンバー変数

名前

アプリの名前

文字セット

適用されるエンコードセット、デフォルトはUTF-8です

ソース言語

エンコードに使用される言語と地域のID番号。複数の言語を開発する場合に必要です。

デフォルトはUTF-8です

言語

アプリに必要な言語と地域のID。デフォルトはsourceLanguageです

ランタイムパス

実行時のパス、たとえばグローバルステータスはデフォルトでこのパスに保存されます

アプリケーション.ランタイムについて考える

拡張パス

サードパーティの拡張機能を配置するパス、デフォルトは application.ext です

タイムゾーン

タイムゾーンを取得または設定します

ロケール

時間、数値などのローカライズに使用されるローカリゼーション オブジェクト

グローバルセート

永続化されるグローバル状態配列 (statePersister によって実装)

コンポーネント

コアメッセージ

フレームワーク層のコンテンツを翻訳し、複数の言語をサポートします

メッセージ

アプリケーション層のコンテンツを翻訳し、複数の言語をサポートします

db

データベースコンポーネント

エラーハンドラ

例外処理コンポーネント。アプリと連携してすべての例外を処理します

セキュリティマネージャー

セキュリティ管理コンポーネント

州永続

状態永続コンポーネント

urlマネージャー

URL管理コンポーネント

リクエスト

リクエストコンポーネント

フォーマット

フォーマットコンポーネント

2.6、WebAppアプリケーション

各 Web リクエストは WebApp アプリケーションによって処理されます。つまり、WebApp アプリケーションは http リクエストを処理するための実行環境を提供します。 WebApp アプリケーションは CWebApplication クラスです。その主な役割は、URL 内のルートに基づいて、対応するコントロール クラスを作成することです。次の図は、主に 3 つのステップで構成されるコントローラーの作成プロセスを示しています。

1. メンバー変数controllerMapを検索して、対応するControllerMapが最も高い優先度を持つかどうかを判断します

2. サブモジュールを検索して、対応するコントローラーがあるかどうかを確認します 3. ControllerPath とそのサブフォルダーを検索します

コントローラーを探すプロセス

入力ルートは: seg1/seg2/seg3

createController(‘seg1/seg2/seg3’,$app)を呼び出します

1

controllerMapでID seg1のコントロールクラスを探します

createController(‘seg2/seg3’,

)を呼び出します

$subModule)

2は存在しません

再帰呼び出し

ID seg1 のサブモジュール内で

を探しています

は存在しません

3

ControllerPath パスの下でレイヤーごとに探します

ControllerPath/seg1/Seg2Controller.php は存在しますか? ControlId は /seg1/seg2 です

存在しません ControllerPath/seg1/seg2/Seg3Controller.php は存在しますか?

ControlId は /seg1/seg2/seg3 です

追加された重要なメンバー変数、メンバー関数、およびコンポーネントを以下の表に示します。

カテゴリー

名前

手順

メンバー変数

デフォルトコントローラー

デフォルトのコントロールクラス、コントローラーが指定されていない場合、このコントローラーが使用されます

レイアウト

デフォルトのレイアウト、コントローラーがレイアウトを指定しない場合、このレイアウトが使用されます

コントローラーマップ

コントローラーマッピングテーブル、特定のルートのコントローラーを指定します

テーマ

テーマを設定します

コントローラー

現在のコントローラーオブジェクト

コントローラーパス

コントローラーファイルへのパス

ビューパス

ビューレイヤーファイルのパス、デフォルトはprotected/views/

システムビューパス

システムビューファイルのパス、デフォルトは protected/views/system/

レイアウトパス

レイアウト ファイルへのパス、デフォルトは protected/views/layouts/

コンポーネント

セッション

セッションコンポーネント

資産マネージャー

プライベートjs、css、画像を公開するためのリソース管理コンポーネント

ユーザー

ユーザーコンポーネント、ユーザーログインなど

テーママネージャー

テーマコンポーネント

認証マネージャー

権限コンポーネントはロールベースの権限制御を実装します

クライアントスクリプト

クライアント側のスクリプト管理コンポーネント、JS および CSS コードを管理します

3. システムコンポーネント

3.1、ログルーティングコンポーネント

すべての Web システムは動作中にログを記録する必要があります。開発段階ではログをファイルまたはデータベースに記録できるため、開発を迅速化できます。 Yii はログ処理において次の 2 つの重要なタスクを実行しました:

1. 各 HTTP リクエストでは、複数のログ (データベース更新ログ/他のシステムとの対話ログ) を記録する必要がある場合があります。たとえば、特定の HTTP リクエストで 18 個のログを記録する必要がある場合、ログごとに 1 回ハードディスクに書き込むか (つまり、18 個のハードディスクに書き込む)、それともリクエストが完了したときに一度にハードディスクに書き込む必要がありますか?終わりかけていますか?明らかに、これらのログを最初に php 配列に保存した方が、リクエストが終了しそうになったら、配列内のすべてのログを一度にハードディスクに書き込む方が高速です。

2. 各ログは、ログの重要度レベルとログのビジネス ロジックの 2 つの側面から分類できます。以下の表を使用してください

「Baidu Creative Expert」製品のログを次の 2 つの次元で説明するには:

ビジネスロジック

重大度レベル

データベースログ

ユーザーセンターインターフェースログ

DRMCインターフェースログ

Memcache ログ

トレース

情報

プロフィール

警告

エラー

ビジネスロジックに従って、データベース操作ログ、ユーザーセンターインターフェースログ、Drmcインターフェースログ、Memcache更新ログなどに分割されます。

重大度レベルに応じて分類されます: トレース、情報、プロファイル、警告、エラー。さまざまなビジネス ロジックのログ (データベース ログ、他のシステムと対話するログ) を別の

に記録したい場合があります。

ファイルなので、カテゴリ別に表示できます。エラー ログは一般に重大であるため、すべてのエラーを別のファイルまたは mongodb に記録することもできます。 Yii のログルーティングコンポーネントは、さまざまなタイプのログをさまざまな宛先 (ファイル、データベース、メールボックス、ページ) にルーティングできるため、ログの維持および管理が非常に便利になります。

以下は、ログ ルーティング コンポーネントの構成です。この構成は、さまざまなビジネス ロジックのログを別のファイルに記録し、エラー ログを error.log ファイルに個別に記録し、開発プロセス中に重大なログを電子メールに直接送信します。ページ上のログにより開発がスピードアップされます。具体的な構成は次のとおりです:

'log'=>array(

'class'=>'CLogRouter', 'routes'=>array(

array(//データベースログはdb.logに記録されます 'class'=>'CFileLogRoute', 'categories'=>'db.*', 'logFile'=>'db.log',

)、

array(//ユーザーセンターとのやりとりのログはuc.logに記録されます 'class'=>'CFileLogRoute', 'categories'=>'uc.*',

'logFile'=>'uc.log',

)、

array(//Drmcとのやり取りのログはuc.logに記録されます 'class'=>'CFileLogRoute', 'categories'=>'drmc.*', 'logFile'=>'drmc.log 、

)、

array(//すべてのエラー ログは error.log に記録されます 'class'=>'CFileLogRoute', 'levels'=>'error', 'logFile'=>'error.log',

)、

array(//ユーザー センターは非常に重要であるため、すべてのユーザー センターのエラー ログは電子メールで送信する必要があります

'クラス'=>'CEmailLogRoute'、'カテゴリ'=>'uc.*'、'レベル'=>'エラー'、'メール'=>'admaker@baidu.com'、

)、

array(//開発プロセス中に、すべてのログがページの下部に直接出力されるため、ログを表示するためにサーバーにログインする必要はありません

'クラス'=>'CWebLogRoute' 'レベル'=>'トレース、情報、プロファイル、警告、エラー',

)、

)

上記のコードから、Yii のロギングが設定配列によって駆動されていることがわかります。次に、Yii のログを確認します

詳細な分析のための処理。次の図は、Yii でのログ処理のプロセスと原理を説明しています:

1. ログルーティングコンポーネントの設定に従って複数のロギングオブジェクトを生成します

ログルーティングコンポーネント

ロギングオブジェクト 1

db.log

2. ログをログバッファに保存します

ログバッファ

3. バッファがいっぱいになったとき、またはリクエストが終了したときにログルーティングコンポーネントに通知します

ロギングオブジェクト 2

。 。 。

uc.log

ロギングオブジェクト i

5. 指定した出力先にログを出力します

メールログを送信

4. 各ログオブジェクトはバッファから必要なログを取り出します

ロギングオブジェクト N

ページへのログ出力

HTTP リクエスト中のログ処理プロセスは次の 5 つの段階に分かれています:

ステップ1: ログルーターの構成情報に基づいて、各ロギングオブジェクト、つまりCFileLogRoute、

を生成します。

CEmailLogRoute オブジェクトと CWebLogRoute オブジェクト、ログ ルーティング コンポーネントはこれらのオブジェクトを均一に管理します。

ステップ 2: プログラマーはログ インターフェイス (以下の表を参照) を呼び出して、すべてのログを php 配列バッファーに一時的に保存します。

ステップ 3: バッファーがいっぱいになるか、リクエストの処理が終了すると、Flush イベントがトリガーされ、ログを取得するようにログ ルーティング コンポーネントに通知されます

ステップ 4: 各ログ オブジェクトは、データベース ログ、ユーザー センター インタラクション ログ、エラー レベル ログなど、必要なログを取り出します。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。