PHP使用语言结构与魔术方法的组合

12

这个问题引起了我的好奇心,想要了解如何结合PHP的魔术方法和语言结构。我已经创建了一个演示代码:

<?php
class Testing {

    public function scopeList() {
        echo "scopeList";
    }

    public function __call($method, $parameters) {
        if($method == "list") {
            $this->scopeList();
        }
    }

    public static function __callStatic($method, $parameters) {
        $instance = new static;
        call_user_func_array([$instance, $method], $parameters);
    }
}

//Testing::list();
$testing = new Testing();
$testing->list();

为什么Testing::list()会抛出语法错误,而$testing->list()却不会?

由于PHP保留关键字,两者都应该失败?


@deceze也许可以。但我认为在这里举个例子会更清晰明了?我想展示一下,在这个例子中魔术方法是如何工作的... - shock_gone_wild
当然这与魔术方法有关。你甚至不能声明一个名为list()的函数,因为list是保留关键字。 - shock_gone_wild
可以这么说,但这并不改变问题的本质,即 ::list() 被捕获为语法错误而 ->list() 不是。 - deceze
1
我认为最终的答案基本上可以归结为:“PHP,叹气,对吧?!” ;) - deceze
1
FYI,这里有一个关于PHP的聊天室:http://chat.stackoverflow.com/rooms/11/php 我建议在那里提出问题之前先去询问一下。 - Danack
显示剩余8条评论
3个回答

4

更新 PHP 7

PHP 7解决了所描述的问题,并实现了一项名为上下文敏感词法分析器的功能,正如marcio所说。

你的代码将与PHP 7一起简单工作。


PHP 7之前的情况

在PHP甚至意识到__callStatic()方法可用之前,语法错误就会被抛出,这发生在解析阶段。

你所描述的行为似乎是PHP解析器中的一个bug,至少是应该在文档中描述的不一致性。

我会提交缺陷报告。捕捉得好!


更新:OP已经提交了一个缺陷报告,可以在这里找到:https://bugs.php.net/bug.php?id=71157


感谢您的输入。我一直想到解析器可能存在错误,但我没有足够的知识来确定这一点。 - shock_gone_wild
不客气!再次感谢你的发现。不幸的是,(PHP)程序员除了避免使用保留关键字之外,在这里无能为力。我想听听PHP核心开发人员对此的意见,也就是说他们是否会去修复它或者说在那个上下文中不要使用“list”。 - hek2mgl
是的,我对这种东西感兴趣 ;) 否则我也不会做研究。我已经提交了一个错误报告,但仅在“文档问题”的情况下。我认为这不是一个“真正”的错误,而是一种不一致性。 - shock_gone_wild
请注意,在这里有一个关于PHP的聊天室:http://chat.stackoverflow.com/rooms/11/php。在报告“错误”之前,我建议您先在那里提问。 - Danack
1
@Danack 虽然我不会说在报告 PHP bug 之前去 Stackoverflow 上的 PHP 聊天室是终极实例,但我同意在这种情况下它会很有帮助。 - hek2mgl
显示剩余5条评论

4

1
哦,我不知道那个。这应该是被接受的答案。 - hek2mgl
感谢您的信息 ;) 但由于托管限制,对我来说(可能也是许多其他人)PHP 7.0还不是一个选择。正如我所说,我知道保留关键字的限制,但OP中的情况看起来相当奇怪和不一致。 - shock_gone_wild

0
在我看来,这是因为保留字,
如果你用 call_user_func_array(['Testing','list'],[]); 替换 Testing::list();,它就能按预期工作了。

1
我熟悉保留字,这就是为什么我发布了指向PHP文档的链接。但是,如果我静态调用list(),为什么会失败,而在实际对象上调用list()则不会失败呢?__callStatic()魔术方法应该处理这个问题。 - shock_gone_wild
虽然这并不是问题的答案,但我还是点赞了,因为它提供了一个解决方法,对于其他遇到类似问题的人可能会很有帮助。 - hek2mgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接