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() { // 🙆🏻♀️ OKパターン: // 暗黙的に現在の名前空間が修飾され、問題なくインスタンスの生成ができる $car = new Car(); // 🙅♀️ NGパターン: // 名前空間が修飾されずクラスが見つからないためエラー // Fatal error: Class 'Car' not found in /var/www/... $className = 'Car'; $car = new $className(); } }
このエラーを解決するにはどうすればいいでしょうか?
解決方法
完全修飾形式(名前空間まで含めた完全な指定)でクラスを指定するか、Car クラスを別途 use 句で指定することで解決できます。
以下は完全修飾形式でクラスを指定する場合の例です。
<?php namespace SampleVendor\Entity class CarCreator { public function create() { $className = __NAMESPACE__ . '\\' . 'Car'; $car = new $className(); } }
マジック定数の __NAMESPACE__
で現在の名前空間名の文字列を取得できるので、これを先頭に付けてクラスを指定します。