概要
変数にClass名を入れて、別クラスでインスタンス化 or 静的に呼び出したい
- 共通で使用するクラス
- 適当なクラス
- 基底クラス(今回は登場しません)
- バリデーションクラス(今回は登場しませんが、staticなvalidate()という関数を持っています。)
の4つが前提として存在します。
詰まった時のコード
適当なクラス extends 共通クラス{
// 省略
// リポジトリのクラス名を返す
protected function getValidationClassName(): string
{
return 'TestClassName';
}
// 省略
}
共通クラス extends 基底クラス{
// 省略
$validate_class_name = $this->getValidationClassName();
$error_validate = $validate_class_name::validate();
var_dump($error_validate);
// 実行結果////////////////
--> $error_validateを表示しようとするとエラーになる
}
どうやら、$validate_class_name::validate($row_data);
の部分でエラーが出ているようです。
ベタ書きで、
$error_validate = TestClassName::validate($row_data);
としたところうまくいきましたが、何が原因なのかわかりませんでした。
クラス名を変数に入れると動かないのか?
PHP: クラスの基礎 - Manual
を見る限りだと、そういうわけでもなさそうです。
解決したコード
適当なクラス extends 共通クラス{
// 省略
protected function getValidationClassName(): string
{
return TestClassName::class;
}
// 省略
}
共通クラス extends 基底クラス{
// 省略
$validate_class_name = $this->getValidationClassName();
$error_validate = $validate_class_name::validate($row_data);
var_dump($error_validate);
// 実行結果////////////////
--> 正常に$error_validateが表示される
// 省略
}
原因は、
return TestClassName::class;
の部分でした。
return 'TestClassName'
がダメで、
return TestClassName::class;
がうまくいく理由は、
名前空間が解決できていないこと が根本の原因でした。
公式に書いてありましたね...
class キーワードでもクラス名の解決を行うことが出来ます。 クラスの名前が ClassName になっているクラスの完全修飾名を取得するには、 ClassName::class を使います。 これは、名前空間付きのクラスに使うと特に便利です。
同じような詰まり方する人少ないと思いますが、どなたか参考になれば幸いです。