使用方法

时间:2015-07-03 20:44:38

标签: php oop laravel laravel-4 laravel-5

在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可能是过度杀戮。

2 个答案:

答案 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

演示:https://3v4l.org/sdBss