6

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

 $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()),在这种情况下,foo() 的返回值被放入 $a。

这让我认为应该首先评估 = 。然后!然后是&&,这不会导致无限循环。

4

2 回答 2

2

您的代码评估如下:

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

这就是您看到无限循环的原因(只要$z >= 11,$apns为假,则条件始终为真)。这种优先级的原因是特殊规则只适用!左边的赋值有效(优先级低于=)。它对右边的布尔运算符没有影响,它的行为就像在任何理智的语言中一样。

你的风格很糟糕。试试这个,它更具可读性,只是最终值不同$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);
}
于 2013-08-29T19:35:03.350 回答
2

您的代码清楚地说明了为什么总是将所有条件放在括号中是一个好习惯(代码块也是如此。即使是单行符也应该用{and包围})。因此,而不是容易出错:

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

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

你会安全的。

于 2013-08-29T19:31:18.400 回答