腹が減ってはなんとやら

大学院博士課程から脱落しました。

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を見に行きます。

課題

  • スコープ定義演算子の使いドコロがよく分からん。