この記事では、主に PHP CodeIgniter フレームワークの動作原理に関する研究を紹介し、次にその動作原理を要約します。必要な方は参照してください。それに
CodeIgniter (以下、CI、公式ウェブサイト、中国ウェブサイトと呼びます) は、小さいながらも強力で、シンプルかつ軽量で、優れた拡張性を備えた人気の PHP フレームワークです。一方、CI は時代に追いついていず、PHP5.3 以降の一部の機能をサポートしていないため、比較的古いプロジェクトに適しています。それでも、CI は依然として優れたフレームワークであり、コアが小さく、ソース コードが洗練されており、学習に適しています。
CIは使いやすく、Webアプリケーションを簡単に開発できます。まずはCIワークフロー図を見てみましょう(ここの内容はhttp://codeigniter.org.cn/user_guide/overview/appflow.htmlから引用しています)
、
1.index.php は、CodeIgniter の実行に必要な基本リソースを初期化するフロントエンド コントローラーとして機能します。
2.ルーターは HTTP リクエストを調べて、誰がリクエストを処理すべきかを決定します。
3. キャッシュ ファイルが存在する場合、通常のシステム実行シーケンスをバイパスし、ブラウザに直接送信されます。
4. セキュリティ。 HTTP リクエストとユーザーが送信したデータは、アプリケーション コントローラーがロードされる前にフィルタリングされます。
5. コントローラーは、モデル、コア ライブラリ、ヘルパー関数、および特定のリクエストを処理するために必要なその他のリソースを読み込みます。
6. 最終ビューでは、Web ブラウザに送信されたコンテンツがレンダリングされます。キャッシュがオンになっている場合は、ビューが最初にキャッシュされるため、今後のリクエストに使用できるようになります。
上記は一般的なプロセスを示しています。では、ブラウザーでレンダリングされたページを見ると、プログラムは内部的にどのように正確に動作するのでしょうか?
以下は、CI フレームワークによってロードされる主なファイルの実行順のリストと、それらの機能の簡単な紹介です。
利用環境(ENVIRONMENT)、フレームワークパス(system_path、BASEPATH)、アプリケーションディレクトリ(application_folder)、アプリケーションパス(APPPATH)などを定義し、CIコアファイルをロード(require)します
02. BASEPATH/core/CodeIgniter.php (ps. 実際には、BASEPATH には最後のファイル区切り文字 '/' が含まれていますが、より明確に表示するためにここに追加の '/' が追加されています)
フレームワーク全体の中核部分であるシステム初期化ファイルは、ここで一連の基本クラスをロードし、このリクエストを実行します
03.BASEPATH/core/Common.php
共通ファイルには、load_class()、get_config() など、グローバルに使用するための一連の基本関数とパブリック関数が含まれています
04. BASEPATH/コア/ベンチマーク
これは、アプリケーションの各ステージの実行ポイントをデフォルトでマークして実行時間を取得するベンチマーク クラスです。監視ポイントを自分で定義することもできます。
05.BASEPATH/core/Hooks.php
CI_Hooks はフレームワーク拡張の中核となるフック クラスで、プログラムで許可されているさまざまな段階でフック ポイントを挿入し、カスタマイズしたクラスや関数などを実行できます。
06. BASEPATH/core/Config.php
構成ファイル管理クラス、構成のロード、読み取り、または設定
07. BASEPATH/core/URI.php、BASEPATH/core/Router.php
URI クラスは、要求された URI を解析するのに役立ち、Router クラスで使用するために URI を分割する一連の関数を提供します
08.BASEPATH/core/Router.php
ルーティング クラスは、要求された URI とユーザー設定のルート (APPPATH/config/routes.php) を介して、ユーザー リクエストを指定された処理関数 (通常はコントローラー インスタンスのアクション関数) に配信します
09. BASEPATH/core/Output.php、BASEPATH/core/Input.php
入力クラスはリクエストの入力パラメータを処理し、それらを取得する安全な方法を提供します。出力クラスは最終的な実行結果を送信し、キャッシュ機能も担当します
10.BASEPATH/core/Controller.php
コントローラーの基本クラスはシングルトン モードを使用してインスタンスを外部に提供し、アプリケーション全体の中心となります。これはスーパー オブジェクトであり、アプリケーションにロードされたクラスはコントローラーのメンバー変数になることができます。これは非常に重要なので、後で説明します。
11. APPPATH/controllers/$RTR->fetch_directory().$RTR->fetch_class().'.php'
ルーティング関数を通じてコントローラー名を取得し、実際のコントローラークラス(サブクラス)をインスタンス化します
12.BASEPATH/core/Loader.php
CI_Loader は、さまざまなクラスライブラリ、モデル、ビュー、データベース、ファイルなどをアプリケーションにロードし、コントローラーのメンバー変数として設定するために使用されます
13. call_user_func_array は処理関数を呼び出します
ルーティングにより、アクション関数名を取得し、Controller->action()関数を呼び出し、アプリケーションロジックを処理します。実際の業務処理ロジックはアクション関数内に記述されます
。
14. $OUT->_display() はコンテンツを出力します
上記はアプリケーション全体の最も基本的な処理の流れです。以下では、コア コンテンツ コードを選択して説明し、CI の理解を深めます:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
//*BASEPATH/system/core/Common.php //引导文件中Benchmark、Hooks、Config等都是过这个関数数进行进行的 関数 &load_class($class, $directory = 'ライブラリ', $prefix = 'CI_') { //记录追加ダウンロード过的类 static $_classes = array();
// 已经加下过,直接读取并返 if (isset($_classes[$class])) { $_classes[$class]を返す; }
$name = FALSE;
// 在指定目录寻找要追加ダウンロード的类 foreach (array(APPPATH, BASEPATH) as $path) { if (file_exists($path.$directory.'/'.$class.'.php')) { $name = $prefix.$class;
if (class_exists($name) === FALSE) { require($path.$directory.'/'.$class.'.php'); }
休憩; } }
// 見つかりません if ($name === FALSE) { exit('指定されたクラスが見つかりません: '.$class.'.php'); }
//ロードされたばかりのクラスをトレースして記録します。is_loaded() 関数は以下です is_loaded($class);
$_classes[$class] = 新しい $name(); $_classes[$class]を返す; } //ロードされたクラスを記録します。この関数はロードされたすべてのクラスを返します 関数 &is_loaded($class = '') { static $_is_loaded = array();
if ($class != '') { $_is_loaded[strto lower($class)] = $class; }
$_is_loaded を返す; }
//*BASEPATH/system/core/Controller.php クラス CI_Controller {
プライベート静的 $instance;
パブリック関数 __construct() { self::$instance =& $this;
// ブート ファイル (CodeIgniter.php) 内のすべてのクラス オブジェクトを初期化します (つまり、今のステップ 4、5、6、7、8、9)、 //コントローラークラスのメンバー変数として登録し、このコントローラーをスーパーオブジェクト化します foreach (is_loaded() as $var => $class) { $this->$var =&load_class($class); } //Loader オブジェクトをロードし、Loader オブジェクトを使用してプログラムに一連のリソースをロードします $this->load =&load_class('Loader', 'core');
$this->load->initialize();
log_message('debug', "コントローラ クラスが初期化されました"); }
//この関数は、コントローラーの単一インスタンスを外部に提供します パブリック静的関数 &get_instance() { self::$instance を返す; } }
//*BASEPATH/system/core/CodeIgniter.php // 基本コントローラークラスをロードします BASEPATH.'core/Controller.php'が必要です;
//このグローバル関数を通じて、コントローラーのインスタンスが取得され、スーパーオブジェクトが取得されます。 //プログラム内の他の場所でこの関数を呼び出すことで、フレームワーク全体を制御できることを意味します 関数&get_instance() { return CI_Controller::get_instance(); }
//対応するコントローラークラスをロードします // 注: Router クラスは自動的に router->_validate_request() を使用してコントローラーのパスを確認します if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php')) { show_error('デフォルトのコントローラーをロードできません。Routes.php ファイルで指定されたコントローラーが有効であることを確認してください。'); }
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
$class = $RTR->fetch_class() //コントローラークラス名 ;$method = $RTR->fetch_method() //アクション名 ;
//…..
//リクエストされた関数を呼び出す // クラス/関数を除く URI 内のセグメントも、呼び出された関数に渡されます call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
//最終コンテンツをブラウザに出力します if ($EXT->_call_hook('display_override') === FALSE) { $OUT->_display(); }
//*BASEPATH/system/core/Loader.php //Loader クラスのロード モデルの例を見てください。コードの一部のみがここにリストされています パブリック関数モデル($model, $name = '', $db_conn = FALSE) { $CI =& get_instance(); if (isset($CI->$name)) { show_error('ロードしているモデル名は、すでに使用されているリソースの名前です: '.$name); }
$model = strto lower($model);
//モデルクラスのパスに従って順番に照合し、見つかった場合はロードします foreach ($this->_ci_model_paths を $mod_path として) { if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) { 続き; }
if ($db_conn !== FALSE AND ! class_exists('CI_DB')) { if ($db_conn === TRUE) { $db_conn = ''; }
$CI->load->database($db_conn, FALSE, TRUE); }
if ( ! class_exists('CI_Model')) { load_class('モデル', 'コア'); }
require_once($mod_path.'models/'.$path.$model.'.php');
$model = ucfirst($model);
//ここでもモデルオブジェクトはコントローラークラスのメンバー変数として登録されています。ローダーは他のリソースをロードするときにもこれを行います $CI->$name = 新しい $model();
$this->_ci_models[] = $name; 戻る; }
// モデルが見つかりませんでした show_error('指定したモデルが見つかりません: '.$model); }
//*BASEPATH/system/core/Model.php //__get() は、未定義の変数の値を読み取るときに呼び出されるマジックメソッドです //以下は Model 基本クラスによる __get() 関数の実装です。これにより、Model クラス内でその変数をコントローラー クラス内で直接読み取ることができます ($this->var など)。 関数 __get($key){ $CI =& get_instance(); $CI->$key を返す
|