在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(在使用局部变量(在方法中(而不使用类变量时允许动态类名。
我也试着把它放在一个seprate方法getModelName()
方法中,但得到了同样的错误。
$this->getModelName()::find(1);
每次调用一个新类(new $this->modelName
(不是一个好的解决方案。
我曾考虑过使用PHP的Reflection
,但不知道如何在每次都不初始化新类的情况下做到这一点。由于它是在使用本地字符串时工作的,所以看起来Reflection
可能是一个过度终止。
这是由于PHP解析器的工作方式(高达PHP 5(。T_PAAMAYIM_NEKUDOTAYIM
令牌(::
(只允许在T_STRING
(表示类名,而不是引号内的字符串(之后,或者自PHP 5.3起,只允许在T_VARIABLE
之后。
但是您的代码将在PHP7中工作,在那里解析器已经从根本上进行了重新设计(请参阅:https://wiki.php.net/rfc/abstract_syntax_tree)
演示:https://3v4l.org/sdBss
您可以使用call_user_func或call _user_func_array来调用类的方法,该方法的名称存储在对象的属性中:
call_user_func(array($this->modelName, 'find'), 1)
或
call_user_func_array(array($this->modelName, 'find'), array(1))