2015-04-01 57 views
5

我无法掌握下面列出的代码中的评估逻辑。有谁知道为什么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

什么PHP说的是,它不能保证像操作的数学秩序秩序。它可能在每个当前版本和系统中具有相同的顺序,并且工作方式完全相同。他们表示,在更高版本中进行更改可能会改变结果,并且不能保证其始终如一。 – 2015-04-01 20:04:34

回答

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中。

我相信他们错过了至关重要的最后一个字有:第一(不,我读书笔记失去位的含义的)。

根据PHP自己的规则,我们假设先进先出顺序!$a应该先评估。如果$a目前是nullundefined,那么!$a将等于true(它将被评估并且结果将被丢弃)。之后,foo()将被评估,并且其返回值将被分配给$a(即使我们假设为FIFO,如果要将其结果分配给某个东西,则必须先评估foo())。此作业的结果将通过if进行评估,并且会导致作者想要的完全相反的值。

我没有C专家,但有点搜索也导致了我这个answer它引用的是C90标准:

(C90,6.3)“除了由语法指示或更高版本另有规定(对于函数调用运算符(),& &,||,?,顿号,运营商)的子表达式的计算顺序和顺序副作用的发生都是unspecitied”

由于PHP它建立在C上,它可以继承它的一些ecc entricities。

+0

因此,基本上在同一行上使用'$ b ++'和'$ b'就像巧克力的普通盒子。 – developerwjk 2015-04-01 20:07:40

+0

@developerwjk:哈哈:-P我会牢记这一点。 – mhall 2015-04-01 20:43:20

+0

我想也许PHP看到'$ b'和'$ b = $ b'等价,就像会优化愚蠢的任务一样,但我猜测事情并非如此。 – mhall 2015-04-01 20:47:59

相关问题