《PHP8上級試験対策》spl_autoload_register() と __invoke() を使ったオートローダー解説

  • URLをコピーしました!

はじめに

PHP ではクラスやインターフェイスを使う際に「まだ定義が読み込まれていない場合」に、自動的にファイルを読み込む仕組み=オートローダーを利用できます。

昔は __autoload() 関数が使われていましたが、PHP7.2.0 で非推奨になり、現在は spl_autoload_register() を使うのが適切です。

本記事では、無名関数と無名クラス(__invoke() メソッド)を使ったオートローダーの動作を解説します。

キーワード: spl_autoload_register / __autoload / __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

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次