PHP中逻辑运算符和赋值运算符的优先级对比

5

最近我遇到了这样的代码片段:

$x = 2 && $y = 3; echo (int)$x.':'.(int)$y;

这段代码的输出是1:3。根据运算符优先级表,我发现逻辑运算符||&&的优先级高于赋值运算符=。所以第一个表达式应该被解析为$x = (2 && $y) = 3;,它变成了$x = (2 && null) = 3;,最终评估为$x = false = 3;。其次,赋值运算符具有右关联性,因此解释器应尝试执行false = 3,这当然是非法的。所以在我看来,上述代码片段根本不应该编译,并且必须抛出解析或运行时错误。但是,脚本产生了1:3的结果。这意味着解释器执行的操作是:

a) $y=3

b) 2 && $y

c) $x = (2 && $y)

为什么会这样而不是按照运算符优先级?


1
你不能将值赋给一个表达式,所以 (2 && $y) = 3 这样的分组是没有意义的。 - deceze
1
那么,如果某个表达式没有意义 - 我们应该改变运算符优先级,以便能够从表达式中提取一些意义吗?如果动态更改的优先级规则与开发人员的意图相反怎么办?我只能同意,如果某个表达式根本没有意义 - 不要运行它或崩溃它。 - Agnius Vasiliauskas
1
¯\(ツ)/¯ 这就是 PHP 的风格了... - deceze
1个回答

3
你所链接的运算符优先级表中有一条独立的注释:
尽管 = 的优先级低于大多数其他运算符,但 PHP 仍然允许类似以下表达式的情况:if (!$a = foo()),此时 foo() 的返回值将被赋给 $a。
因此,实际上,在表达式内部进行的赋值将被视为子表达式。具体发生的时间和方式在文档中并不清楚,文档只是说明“类似”的表达式将按此方式工作。

2
Aron Cederholm 是正确的,表达式将被分解为子表达式并相应地进行评估。这是由 PHP 语法定义的顺序决定的。请参见此处的示例:https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y。 - csb
1
谢谢,我错过了那个神秘的注释。这意味着从现在开始,我不能再信任运算符优先级规则了。 - Agnius Vasiliauskas

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