bootstrap.phpを攻める-CakePHPをもくじとしてPHPを学ぶ04
前回は/app/webroot/index.phpを見ていてbootstrap.phpをincludeしました。 今回はこの中身を見ます。 全部見てたらキリがないので関係ありそうな(僕がそう思ってるだけ)とこだけ見ていくことにします。
多分どっかでspl_autoload_registerって関数を使ってるので見ると160行目あたりで使ってますね。
<?php spl_autoload_register(array('App', 'load'));
これでAppクラスのloadメソッドがクラスローダーになり、未定義のオブジェクトのインスタンスが存在しない場合、このloadメソッドが呼ばれます。 AppクラスはCore/App.phpです。その中のloadメソッドを見ると
<?php public static function load($className) { if (!isset(self::$_classMap[$className])) { return false; } $parts = explode('.', self::$_classMap[$className], 2); list($plugin, $package) = count($parts) > 1 ? $parts : array(null, current($parts)); if ($file = self::_mapped($className, $plugin)) { return include $file; } $paths = self::path($package, $plugin); if (empty($plugin)) { $appLibs = empty(self::$_packages['Lib']) ? APPLIBS : current(self::$_packages['Lib']); $paths[] = $appLibs . $package . DS; $paths[] = APP . $package . DS; $paths[] = CAKE . $package . DS; } else { $pluginPath = self::pluginPath($plugin); $paths[] = $pluginPath . 'Lib' . DS . $package . DS; $paths[] = $pluginPath . $package . DS; } $normalizedClassName = str_replace('\\', DS, $className); foreach ($paths as $path) { $file = $path . $normalizedClassName . '.php'; if (file_exists($file)) { self::_map($file, $className, $plugin); return include $file; } } return false; }
はい533行目あたりにありました。
ここで必要なのは、どのファイル内のクラスをオートロードするかってことやけど、このソースの中で言う$classMapがそれですね。 これはAppクラスのusesメソッドで
<?php public static function uses($className, $location) { self::$_classMap[$className] = $location; }
と定義します。 例えば、ちょっとbootstrap.phpに戻るとspl_autoload_register関数の直後に
<?php App::uses('ErrorHandler', 'Error'); App::uses('Configure', 'Core'); App::uses('CakePlugin', 'Core'); App::uses('Cache', 'Cache'); App::uses('Object', 'Core'); App::uses('Multibyte', 'I18n');
ってな感じでusesをスコープしてます。これでどのクラスをオートロードするのか定義します。他にも定義してるとこあります。 ちなみに、Appクラスはloadメソッドを含んでいるのでオートロードできません。 別でrequireする必要がありますが、bootstrap.phpの140行目で既にrequireされています。 これでオートロードの設定はできたことにして、次回はDispatcherを見に行きます。
課題
- スコープ定義演算子の使いドコロがよく分からん。