__autoloadとSmartyでハマった。

Posted by yonezo in 日記 | Leave a comment
Pocket


php5から、__autoloadという関数が追加され、
includeなどで読み込んでいないクラスに対しても自動で探して読み込んでくれるという便利な機能が追加された。

今までindex.phpの先頭でrequireしまくっていたクラスをスッキリとできる。

で、開発中のフレームワークもそんな感じだったので、思い切って整理整頓。
__autoloadで行こう!と意気込んだのだが、class Not Foundとかのエラーが出て全く機能してくれない。

マニュアル通り、先頭で定義しただけなんだが、これじゃダメなんですかね?

function __autoload($class_name){
    include($class_name.".class.php");
}

しかし、既存のフレームワークじゃなく、テスト用にphpファイル作って動かすと正常に機能するのです。
なので、__autoloadが動かないわけじゃない(当たり前)。

うーんうーんと唸っているうちに、何となくSmartyが悪さしているような気が。
で、調べてみたら案の定悪さしているらしい。

オートローダー

Smarty3はspl_autoload_registerで独自のオートローダーを登録します。もしあなたのコード中に__autoload関数が存在するのなら、 それを明示的に__autoloadスタックに登録しなければなりません。 詳しくは、http://us3.php.net/manual/en/function.spl-autoload-register.php を御覧下さい。
参考:Smarty2.0からSmarty3.0への変更点

でもって、spl_autoload_registerってヤツを調べますが、ナンノコッチャ意味が分からない。
とりあえず__autoload関数は一度しか呼べないのだが、spl_autoload_registerだと複数の__autoloadが出来るようになると。
説明の仕方が間違っているが、そんな感じで便利になるらしいと。

つまり、Smartyがspl_autoload_registerを使っているので、あんたのソース中ではもう__autoload関数は使えねーよ!

という事らしい。(多分間違っている)
で、以下のように修正したら動いてくれた。

function autoloader($class_nm){
	if(file_exists($class_nm.".class.php")){
		include($class_nm.".class.php");
	}
}
spl_autoload_register("autoloader");

Smartyがいろいろとクラスを呼び出すらしく、一応file_existsで存在を確認してからincludeしてあげないとWarningが出る。

あと、このサンプルについてですが前提としてクラスのファイル名を「~.class.php」という規則で設置しているという事になっていますので、あしからず。

この__autoloadの他にも__callとかいろいろあって、とにかく定義されていなくてもphpが探してくれますよ、もしくは未定義でもデフォの関数を実行しますよ系の親切な機能がphp5から結構追加されているぽい。

これはうまく利用すれば、かなり便利に使えそう。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です