使用方法返回的动态类名时出现Laravel错误


Laravel error when using dynamic class names returned by method

在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_funccall _user_func_array来调用类的方法,该方法的名称存储在对象的属性中:

call_user_func(array($this->modelName, 'find'), 1)

call_user_func_array(array($this->modelName, 'find'), array(1))