【问题标题】:Laravel error when using dynamic class names returned by method使用方法返回的动态类名时 Laravel 错误
【发布时间】:2015-07-03 20:44:38
【问题描述】:

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

【问题讨论】:

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


    【解决方案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

    【讨论】:

    • 感谢您的解释。
    【解决方案2】:

    你可以使用call_user_funccall_user_func_array来调用一个类的方法,它的名字存储在对象的属性中:

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

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

    【讨论】:

    • 这行得通,但仍然不能解释为什么会这样。有什么想法吗?
    • 因为它根本不被支持。
    • 自 PHP 5.3 起,允许调用静态方法并使用存储在变量中的动态类名访问静态属性,例如:$a::foo(),但它仍然不允许你的重新尝试做。我也不清楚以这种不寻常的方式调用静态方法有什么好处。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多