さて、SPLの匂いが漂ってきました。
1 | spl_autoload_register(array('App', 'load')); |
なんだ、なんなんだ!spl_autoload_registerって何なんだ! spl_autoload_register - PHP Manual
ん?第一引数に配列を受け取るとは書いてない・・・。 わからん。しょうがないのでソースを読む。PHPのバージョン5.5.7のソース内 ext/php_spl.cの499行目当たりを見ると
1 | 499 if (Z_TYPE_P(zcallable) == IS_ARRAY) { |
うーむ、Cの能力が足りてなくて読み解けないけど、察するに配列の引数1番目のクラスの引数2番目のstatic関数を受け取れるらしい。 今回の例で言えば、App::loadメソッドを__autoloadの関数として登録するということらしい。
App:loadメソッドが__autoloadとして使われるというのは、どういうことなのか・・・? 情弱は、疑問の渦へ・・・ クラスのオートローディング - PHP Manual 要するに! includeの自動化である!
肝は、「ク・ラ・ス」のオートローディングという所。 つまり、インスタンスをnewするタイミングで、__autoload()が呼び出される。
ここまでの話を総合すると、以下のように理解することが出来る。
CakePHPでは、App:load関数を__autoloadとして登録している。
App:usesされた「クラス名、場所」はAppクラスの$_classMap配列へ追加される
$_classMapへ追加されたクラスは、instance化される段階でautoloadによって、includeされる。(予想)
3番めの予想が正しいことを確認するには、App:load関数を読み解く必要がある。 というわけで、ソースを貼り付けようと思ったが、貼り付けても意味は分かりづらいのでやめた。 というわけで、最低限の関数定義はこちら。
1 | public static function load($className) |
つまり、例えば CakePHPにおいてModel/Hoge.phpに書いてあるHogeクラスのインスタンスをnewした場合。
(1) __autoload()が呼び出されApp:load(‘Hoge’)が実行される。 -—–ここから下はload関数の処理——
(2) Appのメンバ変数 $_classMap配列に該当クラス名のキーが存在するかをチェック。無ければfalse返して終わり。
(3) クラス名に「..」が含まれていないかチェック。あったらfalse返して終わり。
(4) ユーザのappディレクトリ、Cakeのappディレクトリ、CakeのLIBRARYの順番にpath + ディレクトリ名 + クラス名 + .php でファイルの存在チェックをする
(5) ファイルが見つかったら、includeして終了 ※ちなみに、ディレクトリ名の部分にPlugin名 + ドット + ディレクトリ名を指定すると、Pluginのロードも出来るようです。いつ使うのかな??
というわけで、CakePHPはユーザのappクラス配下のファイルを第一番にloadするようにautoloaderが動くのが分かりました。 ここを乗り越えると、bootstrap.phpの難しいところは大体終わりです。 次回は、bootstrap.phpの残り部分を読みます。