我在生产中有以下代码似乎导致无限循环。
$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;,这不会导致无限循环。
答案 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);
}