はじめに
PHP ではクラスやインターフェイスを使う際に「まだ定義が読み込まれていない場合」に、自動的にファイルを読み込む仕組み=オートローダーを利用できます。
昔は __autoload() 関数が使われていましたが、PHP7.2.0 で非推奨になり、現在は spl_autoload_register() を使うのが適切です。
本記事では、無名関数と無名クラス(__invoke() メソッド)を使ったオートローダーの動作を解説します。
目次
オートローダーとは?
通常、new Hoge() のようにクラスをインスタンス化しようとした時、そのクラスが未定義なら Fatal error になります。
しかしオートローダーを登録しておけば、PHP は「未定義クラスを呼ぼうとした瞬間」に登録済みの関数やオブジェクトを順番に実行し、クラス定義をロードしようとします。
サンプルコード
まず Hoge.php を作成します:
<?php
declare(strict_types=1);
class Hoge{
}次に同じディレクトリに以下を保存します:
<?php
declare(strict_types=1);
error_reporting(-1);
// オートローダー1: 無名関数
spl_autoload_register(function(string $class):void{
echo "動的関数 1({$class}) \n";
});
// オートローダー2: 無名クラス + __invoke()
spl_autoload_register(new class(){
public function __invoke(...$values){
echo "動的クラス 1({$values[0]})\n";
require_once __DIR__ . '/Hoge.php';
}
});
// クラス Hoge を呼び出す
$obj = new Hoge();
var_dump($obj);実行結果
動的関数 1(Hoge)
動的クラス 1(Hoge)
object(Hoge)#3 (0) {
}なぜこうなるのか?
ASCIIアートで流れを整理してみましょう。
new Hoge()
│
├─> まだ Hoge は未定義
│
├─> オートローダー #1 実行
│ └─ echo "動的関数 1(Hoge)"
│ └─ クラスはロードしない
│
├─> オートローダー #2 実行
│ └─ echo "動的クラス 1(Hoge)"
│ └─ require_once Hoge.php
│
└─> Hoge クラスが読み込まれた!
↓
object(Hoge)👉 つまり「最初のローダーでクラスをロードしなかったため、次のローダーが呼ばれ、そこで初めてファイルを読み込み、最終的にクラスが利用可能になる」という流れです。
ポイント整理
spl_autoload_register()は複数登録できる
→ 登録順に呼び出される__invoke()を持つオブジェクトもコールバックとして登録可能
→ 無名クラスを「関数のように」扱える- 最初のローダーがクラスを読み込まないと、次のローダーに処理が移る
- 結果として、上のサンプルは 正しい挙動
試験対策の観点
__autoload()は非推奨 → 試験では 誤答パターン として出る- 正しくは
spl_autoload_register()を使う - 複数登録が可能で、順番に呼ばれることを理解しておく
__invoke()を持つ無名クラスもオートローダーとして登録できる点は実務でも応用範囲あり
まとめ
このサンプルの結果(「動的関数 1(Hoge)」「動的クラス 1(Hoge)」「object(Hoge)」)は、オートローダーが順番に呼ばれた正しい挙動です。
試験対策としては以下を押さえておきましょう。
__autoload()は古い → 誤答パターンspl_autoload_register()が正しい- 複数登録でき、順番に呼ばれる
- 無名関数でも、
__invoke()を持つオブジェクトでも OK
