PHPで動的にクラス名を指定するとオートロードできない

PHP で動的にクラス名を指定する場合、現在いる名前空間が修飾されないため、
クラス名のみで名前空間内のクラスを指定して new するとクラスを見つけられず致命的なエラーになります。

エラーになる例

クラスファイルのパス構成

例えば PSR-0 規約に準拠して以下のような構成で Car クラスと CarCreator クラスを配置していたとします。

  • /var/www/sample/Vendor/SampleVendor/Entity
    • Car.php
    • CarCreator.php

Car.php

SampleVendor\Entity の名前空間で Car クラスを定義します。

<?php
namespace SampleVendor\Entity

class Car {}

CarCreator.php

この状態で Car クラスと同じ名前空間の CarCreator クラスから Car クラスのインスタンスを生成してみます。
autoload.php は既に読み込まれた状態です。

<?php
namespace SampleVendor\Entity

class CarCreator {
    public function create() {
        // 現在の名前空間が修飾され問題なくインスタンスが生成される
        $car = new Car();

        // 名前空間が修飾されずクラスが見つからずエラー
        // Fatal error: Class 'Car' not found in /var/www/sample/...
        $className = 'Car';
        $car = new $className();
    }
}

このエラーを解決するには完全修飾形式でクラス名を設定するか、
Car クラスを別途 use 句で指定する必要があります。

解決方法

CarCreator.php

以下、完全修飾形式で $className を指定する場合の例です。

<?php
namespace SampleVendor\Entity
class CarCreator {
    public function create() {
        $className = __NAMESPACE__ . '\\' . 'Car';
        $car = new $className();
    }
}

__NAMESPACE__ 定数は現在の名前空間名の文字列なので、これを先頭に付与しておきます。

One thought on “PHPで動的にクラス名を指定するとオートロードできない

コメントを残す

メールアドレスが公開されることはありません。

計算問題(認証) * Time limit is exhausted. Please reload the CAPTCHA.