明滅するプログラマの思索

WEBエンジニアとして勤務している一介の男が、日々気づいたことをまとめるブログです

PHPで require_once / require を使わずにクラスをロードする

PHP でファイルを読み込む際 require_once や require を使うことになりますが、読み込むファイルが膨大になると大量の require_once / require を記述しなくてはいけなくなります。
spl_autoload_register() を使うと、読み込まれていないクラスをコールした際にこちらに登録されているメソッドが呼ばれるので、救済的なロジックを記述することができます。
さらに名前空間を最適に運用することで、少ない労力でクラスファイルのオートロードが実現できます。

名前空間について

PHP名前空間はバージョン5.3で追加されました。
クラスファイルに名前空間を設定することで、別の名前空間に同じクラス名のファイルを作成することができるようになります。

<?php
namespace hoge;
class A
{

}
<?php
namespace fuga;
class A
{

}

上記2つのクラスは、クラス名が同じですが名前空間が異なるため、別々のクラスとして認識されます。
コールする際は名前空間とクラス名をバックスラッシュでつなげて記述します。

<?php
$hoge_a = new \hoge\A();
$fuga_a = new \fuga\A();

名前空間はサブの名前空間を持つことができます。この場合もバックスラッシュで区切ります。

<?php
namespage hoge\fuga;
class A
{
}

$hoge_fuga_a = new \hoge\fuga\A();

名前空間の基本的な運用

名前空間ファイルシステムディレクトリとファイル名の関係に似ています。
そこで、実際の開発においても、名前空間ディレクトリ、クラス名とファイル名をマッチングさせて管理すると、構造が見やすくなります。
例えば、/hoge/A.php というファイルならば名前空間 hoge に属するクラス A、というようにです。
PHPのコーディング規約

PSR-0(日本語)|北海道札幌市のシステム開発会社インフィニットループ

ではそう実装するよう記述されています。

spl_autoload_register() を使った実装

名前空間ディレクトリ、クラス名とファイル名をマッチさせた開発環境で spl_autoload_register() を利用したオートロードの簡単な実装をご紹介します。

<?php
define('PROJECT_PATH', '');
spl_autoload_register('autoload');
function autoload($class_name)
{
    $filename = PROJECT_PATH."/".str_replace('\\', "/", __NAMESPACE__.$class_name).'.php';
    if (is_readable($filename)) {
        require_once($filename);
    }
}

はい、これだけです。
定数の PROJECT_PATH はプロジェクトルートです。適宜設定してください。

spl_autoload_register() を利用することのメリットは、ファイル数分の require_once / require をコールしなくてもよくなる、というだけではありません。
実際の実行プロセスで必要なクラスのみがロードされるため、メモリの節約につながることも大きいと思います。
また、名前空間を適切に利用することでクラスファイル名への自由度が高くなりますし、各クラスの意味づけも容易になると思います。