読者です 読者をやめる 読者になる 読者になる

k-holyのPHPとか諸々メモ

Webで働くk-holyがPHP(スクリプト言語)とか諸々のことをメモしていきます。ソースコードはだいたいWindowsで動かしてます。

stream_resolve_include_path()関数で簡単オートロード

stream_resolve_include_path()はファイル名からinclude_pathを考慮したファイル検索を行なって、ファイルが存在すればパスを返してくれる関数。(5.3.2以降)
http://jp.php.net/manual/ja/function.stream-resolve-include-path.php

この関数を使って、include_path前提の名前空間PEAR形式の両方(PSR-0)に対応したオートロード実装を書いてみました。
※PSR-0については http://scopenote.blogspot.com/2011/02/psr-0.html などを参照

以前のinclude_pathを使ったクラスロードでは、エラー制御演算子や一時的なerror_reporting()変更でinclude/fopen()する方法や、include_pathをPATH_SEPARATORでexplode()してfile_exists()を繰り返す方法が取られていましたが、この関数のおかげでとても楽になりました。

外部ライブラリを使わないただの無名関数なので、ユニットテストの初期化スクリプトなどで使えると思います。

そもそも名前空間よーわからんって方は、こちらも見てくださると嬉しいです。

[追記]
\Foo\Bar\Baz(/path/to/vendor/Foo/Bar/Baz.php) と Foo_Bar_Baz(/path/to/pear/Foo/Bar/Baz.php)といった、名前空間のクラスとPEAR形式のクラスが併設されている時に "Cannot redeclare class \Foo\Bar\Baz" あるいは "Class '\Foo\Bar\Baz' not found" といったエラーが発生します。
(include_pathで名前空間クラスのパスとPEARクラスのパスのどちらが優先されているかによる)

クラスロードでinclude_pathを利用する場合、PSR-0の仕様上この問題を避けるのは難しく、spl_autoload_register()によるオートロードの仕組み上(オートローダをスタックできるため、読み込み失敗即中断というわけにはいかない)、適切な警告を出すことも難しいです。
利用者側で気をつけるしかないのかな…。