我无法掌握下面列出的代码中的评估逻辑。有谁知道为什么PHP在这种情况下评估$b
和$b = $b
的方式不同?
我已在SO上阅读了一些问题并检查了PHP manual。这样做我已经明白“PHP没有(在一般情况下)指定表达式的评估顺序”而“行为可以在PHP版本之间改变或者取决于周围的代码“。我不认为这适用于这种情况。或者是吗?
作为第一个承认这可能不是您日常编码问题的人,我仍然很好奇。偶然发现它试图做一些code golfing。
$a = [[00, 01, 02, 03],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33]];
$b = 2;
echo $a[$b][$b++], PHP_EOL;
$b = 2;
echo $a[$b=$b][$b++], PHP_EOL;
输出 - PHP 5.5.14:
32
22
答案 0 :(得分:10)
这看起来像用于演示未定义评估顺序的manual中的示例。从手册:
运算符优先级和关联性仅确定表达式的分组方式,它们不指定评估顺序。 PHP不会(在一般情况下)指定表达式的计算顺序和代码假设应该避免使用特定的评估顺序,因为行为可以在PHP版本之间或根据周围的代码进行更改。
强调添加
他们给出的例子:
<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3
$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>
您正在获得输出,因为在第一个示例中,索引$b++
正在确定第一个,而在第二个示例中,索引$b=$b
是第一个。
NB
至于为什么这是,我相信一个可能的原因可以通过同一手册页上的这个说明来解释:
尽管=的优先级低于大多数其他运算符,但PHP仍然允许使用类似于以下的表达式:if(!$ a = foo()),在这种情况下,foo()的返回值放入$ a
我相信他们在那里错过了一个至关重要的最后一句话: first (没有,对我来说读这个音符会失去一些意义)。
遵循PHP自己的规则,和我们假设一个FIFO顺序,应首先评估!$a
。如果$a
目前为null
或undefined
,则!$a
将等于true
(将对其进行评估,结果将被丢弃)。接下来,将评估foo()
,并将其返回值分配给$a
(即使我们假设FIFO,如果要分配其结果,则必须首先评估foo()
某事)。此作业的结果将由if
进行评估,并且会产生与作者想要的完全相反的值。
我不是C专家,但是一些搜索也引导我answer引用了C90标准:
(C90,6.3)“除非语法指示或稍后指定(对于函数调用运算符(),&amp;&amp;,||,?:和逗号运算符)。评估顺序子表达式和副作用发生的顺序都是未指明的“
由于PHP是基于C构建的,因此它会继承它的一些怪癖。