理解php中的运算符优先级

时间:2013-08-29 19:27:27

标签: php operators operator-precedence

我在生产中有以下代码似乎导致无限循环。

 $z=1;
 while (!$apns = $this->getApns($streamContext) && $z < 11)
 {
    myerror_log("unable to conncect to apple. sleep for 2 seconds and try again");
    $z++;
    sleep(2);
 }

如何应用导致此行为的优先规则?

http://php.net/manual/en/language.operators.precedence.php

我在文档中看到了这个说明:

  

虽然=的优先级低于大多数其他运算符,但PHP会   仍然允许类似于以下的表达式:if(!$ a = foo())in   在哪种情况下,foo()的返回值被放入$ a。

这让我觉得应首先评估=。那么!然后是&amp;&amp;,这不会导致无限循环。

2 个答案:

答案 0 :(得分:2)

您的代码清楚地说明了为什么始终将所有条件放在括号中的好习惯(同样适用于代码块。甚至oneliner也应该被{和{}包围{1}})。因此,而不是容易出错:

while (!$apns = $this->getApns($streamContext) && $z < 11)

while (!($apns = $this->getApns($streamContext)) && ($z < 11))

你会安全的。

答案 1 :(得分:2)

您的代码正在评估如下:

while (!($apns = ($this->getApns($streamContext) && ($z < 11))))

这就是你看到无限循环的原因(只要$z >= 11$apns为假,所以条件总是为真)。此优先级的原因是特殊规则仅适用于有效赋值的 left 上的!(优先级低于=)。它对右边的布尔运算符没有影响,它的行为与任何理智的语言一样。

你的风格很糟糕。试试这个,它更具可读性,只是$z的最终值不同(如果这很重要,你可以调整break语句。

for( $z = 1; $z < 11; ++ $z ) {
    // note extra brackets to make it clear that we intend to do assignment not comparison
    if( ($apns = $this->getApns($streamContext)) ) {
        break;
    }
    myerror_log("unable to conncect to apple. sleep for 2 seconds and try again");
    sleep(2);
}