在Laravel(4& 5)中,我试图使用动态类名,然后直接调用它们,但如果不首先将它们存储在本地字符串变量中,则会收到致命错误。
假设我有一个基本课程:
class SimpleModel {
private $modelName;
function __construct($id) {
$this->modelName = AnotherModel::getName($id);
}
}
在这些方法中,我可以很容易地做到
$modelName = $this->modelName;
$modelName::find(1);
但是在尝试以下操作时我遇到了致命的错误:
$this->modelName::find(1);
这会触发Symfony\Component\Debug\Exception\FatalErrorException
,消息为
syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
基本上T_PAAMAYIM_NEKUDOTAYIM
是从::
符号生成的语法错误。
无法解决为什么Laravel(或一般来说PHP)在使用局部变量(在方法中)而不是类变量时允许动态类名。
我也尝试将它放在一个单独的方法getModelName()
方法中,但是遇到了同样的错误。
$this->getModelName()::find(1);
每次(new $this->modelName
)实施新课程都不是一个好的解决方案。
我正在考虑使用PHP Reflection
,但不确定如何在不每次实例化新课程的情况下执行此操作。
由于它在使用本地字符串时起作用,因此Reflection
可能是过度杀戮。
答案 0 :(得分:1)
您可以使用 call_user_func 或 call_user_func_array 来调用类的方法,该类的名称存储在object的属性中:
call_user_func(array($this->modelName, 'find'), 1)
OR
call_user_func_array(array($this->modelName, 'find'), array(1))
答案 1 :(得分:1)
这是由于PHP解析器的工作原理(最高为PHP 5)。 T_PAAMAYIM_NEKUDOTAYIM
令牌(::
)仅在T_STRING
之后(表示类名,而不是引号内的字符串)或者自PHP 5.3后T_VARIABLE
。
但您的代码将在PHP 7中运行,其中解析器已经从根本上重做(参见:https://wiki.php.net/rfc/abstract_syntax_tree)