クラスのオートローディング

オブジェクト指向アプリケーションを作成する開発者の多くは、 クラス定義毎に一つのPHPソースファイルを作成します。 最大の問題は、各スクリプトの先頭に、必要な読み込みを行う長いリストを 記述する必要があることです(各クラスについて一つ)。

PHP 5では、これはもう不要です。 spl_autoload_register() 関数で任意の数のオートローダーを登録できて、 クラスやインターフェイスが定義されていなくても自動的に読み込めるようになります。 オートローダーを登録すれば、PHPがエラーで止まる前にクラスをロードする最後の チャンスが与えられます。

ヒント

__autoload() 関数でもクラスやインターフェイスのオートロードができますが、 spl_autoload_register() 関数を使うことをおすすめします。 こちらのほうが、より柔軟に使えるからです (任意の数のオートローダーを登録して、サードパーティのライブラリなどに対応することもできます)。 このため、__autoload() の使用は PHP 7.2.0 以降、非推奨となり、削除されます。

注意:

PHP 5.3 より前のバージョンでは、__autoload() 関数の内部でスローされた例外を catch ブロックでキャッチすることができず、致命的なエラーとなります。 PHP 5.3 以降ではこれをキャッチできるようになりました。ただし、 独自の例外クラスをスローした場合は、その例外クラスが利用可能でなければなりません。 __autoload() 関数を再帰的に用いて、独自の例外クラスをオートロードします。

注意:

オートローディングは、PHP を CLI 対話モード で実行している場合は使用できません。

注意:

クラス名をたとえば call_user_func() などで使用する場合、 ../ のような危険な文字が含まれることもあり得ます。 このような関数にはユーザーの入力を渡さないことをおすすめします。 あるいは最低限 __autoload() の中で入力内容を検証するようにします。

例1 オートロードの例

この例は、 クラス MyClass1 および MyClass2 をそれぞれ MyClass1.php および MyClass2.php からロードします。

<?php
spl_autoload_register
(function ($class_name) {
    include 
$class_name '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2();
?>

例2 オートロードの別の例

この例は、インターフェイス ITest をロードしようとします。

<?php

spl_autoload_register
(function ($name) {
    
var_dump($name);
});

class 
Foo implements ITest {
}

/*
string(5) "ITest"

Fatal error: Interface 'ITest' not found in ...
*/
?>

例3 5.3.0 以降での例外処理つきのオートロード

この例は、例外をスローして try/catch ブロックの動きを示します。

<?php
spl_autoload_register
(function ($name) {
    echo 
"Want to load $name.\n";
    throw new 
Exception("Unable to load $name.");
});

try {
    
$obj = new NonLoadableClass();
} catch (
Exception $e) {
    echo 
$e->getMessage(), "\n";
}
?>

上の例の出力は以下となります。

Want to load NonLoadableClass.
Unable to load NonLoadableClass.

例4 5.3.0 以降での例外処理つきのオートロード - 独自の例外が見つからない場合

この例では、ロードできない独自の例外クラスをスローします。

<?php
spl_autoload_register
(function ($name) {
    echo 
"Want to load $name.\n";
    throw new 
MissingException("Unable to load $name.");
});

try {
    
$obj = new NonLoadableClass();
} catch (
Exception $e) {
    echo 
$e->getMessage(), "\n";
}
?>

上の例の出力は以下となります。

Want to load NonLoadableClass.
Want to load MissingException.

Fatal error: Class 'MissingException' not found in testMissingException.php on line 4