2006-08-28 CakePHPの処理の流れを追ってみよう
CakePHPの処理の流れを追ってみよう(0)
このシリーズは2006年8月28日の日記に追記していくかたちで書いていこうと思います。RSSの出力がどうなるか分かりませんが、1ページで俯瞰できる便利さを取ります。
第2回はcake/bootstrap.phpの中身です。
CakePHPの処理の流れを追ってみよう(1)
URLをリクエストしてから、実際に書いたコ−ドに辿り着くまでを追ってみます。掲載しているコード(のようなもの)は分かりやすくするために省略化したフローチャート的なもので、文法などはまったく考慮していません。分かりやすくなっているかは分かりません。また、正確にトレースできているのかも保証できません(´д`;)。
それでは入り口のindex.phpから。
app/webroot/index.php
define ROOT, APP_DIR, CAKE_CORE_INCLUDE_PATH, WEBROOT_DIR, WWW_ROOT, CORE_PATH, APP_PATH
{
ROOT = '/path/to/cake'
APP_DIR = 'app'
CAKE_CORE_INCLUDE_PATH = ROOT
WEBROOT_DIR = 'webroot'
WWW_ROOT = 'cake/app/webroot/'
if(ini_set){
'include_path' += CAKE_CORE_INCLUDE_PATH + ROOT/APP_DIR/
}else{
APP_PATH = ROOT/APP_DIR/
CORE_PATH = CAKE_CORE_INCLUDE_PATH/
}
}
require CORE_PATH.'cake/bootstrap.php';
$Dispatcher=new Dispatcher();
$Dispatcher->dispatch();
まず各フォルダをdefineしています。
ini_set関数が使える場合、APP_PATHとCORE_PATHは使わずにinclude_pathに追加しています。requireやincludeではAPP_PATHやCORE_PATHが定義されている場合はフルパスで、そうでない場合は相対パスをinclude_pathから探すようになっています。上手いことやってますね。実質ini_set()が実行されAPP_PATHとCORE_PATHはnullになり、「cake内のファイルをapp内にコピーするとapp内のファイルを読み込む」仕様を実現しています(追記:とか思ってたらapp_model.phpはfile_existsでif分岐してrequireしてました) (参考:CakePHPのおいしい食べ方 - ディレクトリ構造2(つぼを知る))。
準備ができたらcake/bootstrap.phpをrequire、Dispatcherを作ってdispatch()メソッドを呼び終了。
cake/bootstrap.phpでは多くのファイルをrequireしています。
URLの調節をなんかやってるようです。
最後にキャッシュが有効になっている場合、viewのrenderCache()を呼び出します。キャッシュが正常に出力されたらdie()するので、後の$Dispatcher->dispatch();は呼ばれずにここで終了します。
cake/dispatcher.php
dispatch() {
$params = $this->parseParams();
$params['controller']
$params['action']
loadController();
if($params['plugin']){
loadPluginModels();
}
$controller =& new $ctrlClass();
$controller->変数いろいろ = 値いろいろ;
$controller->_initComponents();
$controller->constructClasses();
return $this->_invoke();
}
function _invoke(&$controller, ...){
$this->start(){
$controller->beforeFilter();
$controller->components->startup();
}
$controller->$params['action']; //call action
if ($controller->autoRender) {
$output = $controller->render();
}
$controller->afterFilter();
}
dispatch()の最初にparseParams()を呼びリクエストを解析しています(ここでapp/config/routes.phpを読み込んでます)。これでどのcontrollerのどのactionを呼ぶかが決定され、後は怒濤のセットアップ、action実行、後始末。
とりえずcontrollerのaction部分まで辿り着きました。
CakePHPの処理の流れを追ってみよう(2)
今回はbootstrap.phpの中身を簡略化してみます。
cake/bootstrap.php
require 'cake/basics.php'; //関数いっぱい require 'app/config/core.php'; //基本的な設定のdefine require 'cake/config/paths.php'; //フォルダのdefineいっぱい require /* cake/libs/内の */ 'object.php', 'session.php', 'security.php', 'neat_array.php', 'inflector.php', 'configure.php'; //これらはすべてクラスファイルなので、この場で実行されるコードは記述されていない。 $paths = Configure::getInstance(); //この過程で/app/config/bootstrap.phpがrequireされる ここでなんかURLを調べてる。 require 'cake/dispatcher.php'; //model関連の初期化 require 'cake/libs/model/connection_manager.php'; require 'config/database.php'; //←config('database'); require 'cake/libs/model/model.php'; loadModels(){ require app_model.php //ここでModelを全部読み込んでいるようだ。 require models in /app/models/ and $modelPaths } //キャッシュ関連の処理 if(CACHE_CHECK){ $view->renderCache(); }
これまでの流れをまとめるとこんな感じです。
index.php{ define ディレクトリ構造 bootstrap.php{ define 基本設定 require 基本クラス init model if(cache){ renderCache } } $Dispatcher->dispatch(){ //dispatcher.php parse beforeFilter action!! render afterFilter } }
