PHP5 - 赋值操作结果未被解析器视为对象

PHP5 - Assignment operation result not treated as object by parser

提问人:Bastien 提问时间:2/1/2017 最后编辑:Bastien 更新时间:2/1/2017 访问量:145

问:

我对解析错误有点困惑:

class Foo{
    public function some_function(){}        
}

($foo = new Foo())->some_function();

收益 率

PHP 解析错误:语法错误、意外的“->”(T_OBJECT_OPERATOR)、预期为“”、“”或“;”

以下是 php-langspec 对简单赋值表达式的描述:

结果的类型和值是存储(如果有 [见下文])发生后左操作数的类型和值。结果不是左值。

现在据我了解,赋值结果应该等同于变量,除非它不是左值(不可能赋值)。那么为什么会出现错误呢?

我错过了什么吗?

编辑

PHP 版本为 5.5.9

这与链接方法无关,这是一个解析错误,而不是运行时错误。

php 解析 语法 赋值运算符

评论

2赞 Yannick Huber 2/1/2017
您的编译器使用什么 php 版本?
0赞 u_mulder 2/1/2017
缺少 PHP 版本。 我想?5.3
0赞 Bastien 2/1/2017
PHP 版本为 5.5.9
0赞 u_mulder 2/1/2017
eval 显示即使在php5.6
1赞 axiac 2/1/2017
该问题已在 PHP 7 中得到解决。

答:

2赞 NeuronQ 2/1/2017 #1

简短的回答:这些表达式现在在 PHP 7.x 中工作得很好。


长答案:PHP 的“手工制作的解析器”有严重的局限性,尤其是在 PHP < 7.0 中。许多你期望工作的复杂表达式,没有。

但它至少保持了自己奇怪的“对称性”:就像它不适用于将运算符应用于赋值结果一样,它也不适用于应用数组索引运算符。->[...]

例如(在 PHP 5.6.23 上尝试):

>>> ($x = new stdClass())->foo                                
PHP Parse error: Syntax error, unexpected T_OBJECT_OPERATOR on line 1

>>> $x = new stdClass()                                 
=> {#334}           
>>> $x->foo                                             
PHP error:  Undefined property: stdClass::$foo on line 1
>>> // this above is the "correct" error you would expect here


>>> ($x = ['name' => 'J'])['name']                     
PHP Parse error: Syntax error, unexpected '[' on line 1

>>> $x = ['name' => 'J']                
>>> $x['name']           
=> "J"                  

纯属推测:我想修复这些解析器不一致 很简单,但PHP的核心开发人员不这样做的理由 听起来可能像“但是解决这个问题会鼓励一种非常糟糕的编码风格,因为每个人都同意使用赋值的结果是一种不好的做法,所以既然已经有这么多糟糕的PHP代码在野外, 为什么要添加一个修复程序,鼓励人们编写更多糟糕的代码”。值得庆幸的是,PHP 7.0 的理性占了上风。

历史:我过去的一些PHP版本,不记得确切的是什么,甚至像或不可解析的代码,但它在好的代码中具有合法的用途,因此解析器已修复以使其正常工作。my_function()['attr1']$foo->myMethod()->myField

评论

0赞 Bastien 2/1/2017
好吧,基本上,php 解析器甚至不符合语言规范。这当然不会改善我对 php 的看法。
0赞 NeuronQ 2/1/2017
@Bastien同意。人们不会选择使用“PHP作为语言”,而是选择使用“PHP作为平台”,尽管这种语言很可怕。所有关于其创建者的“不共享任何内容,每个请求 1 个进程”的想法。你可以让一群糟糕的开发人员使用带有内存泄漏的库编写有缺陷的代码,并且仍然发布一个工作应用程序,该应用程序可以在数十台服务器上轻松扩展,为数以百万计的用户提供服务(“这是一个错误,但它只崩溃了 0.01% 的请求,所以客户不在乎,资金不断流动”的魔力 - 使用 nodejs 或 go, 你通常会有一个错误来破坏你的整个应用程序)
0赞 NeuronQ 2/1/2017
@Bastien但作为一名开发人员,我上面提到的只能转化为“更差的薪水”和“更多的压力”,除非你有一种不自然的天赋来清理别人的代码混乱:)