notes icon indicating copy to clipboard operation
notes copied to clipboard

PHP,请放弃使用 and 与 or 两个逻辑运算符

Open lanlin opened this issue 5 years ago • 2 comments

背景

表面看起来,好像 and&&, or|| 是可以互相替代的。 然而,事实其实并非如此。

$a = true and false;
$b = true && false;

上面的例子,$a 会得到 true 值。而 $b 才是 false

原因

image

如上图所示,运算符中,and xor or 这哥三就是垫底的货。 它们的优先级还不如赋值运算符,所以得到例子中的结果也就不足为奇。

吐槽

感觉用 andor 语义上特别容易理解,代码看起来也更漂亮。 奈何优先级居然跟 &&|| 差那么多,完全就是银样蜡枪头啊。 我也不敢问啊,怕别人闲我智商太低。

为了避免犯错,建议:弃用!

lanlin avatar Apr 28 '19 03:04 lanlin

其实or这类运算符应该用在的地方是只需要代码的副作用(具体地说,比如guard,log),而不是表达式的时候。 举个例子,do something并赋值,并在出现问题时记录,在一行里怎么写呢,伪代码如下:

$result = query_database($SQL) or query_error(__FILE__, __LINE__);

赋值表达式本身是有值的,query_error根据赋值结果执行。当然现在基本都是用异常处理,我也是从early PHP5时代的代码里学来的。

acgrid avatar May 14 '19 10:05 acgrid

@acgrid 事实上,我之前也像你那个例子的做法。 多数时候用来简化 if 和控制流程。

if (!empty($a))
{
    $b = call_foo_func();
}

empty($a) or $b = call_foo_func();

一直都觉得这种写法很精简很炫, 直到我不知不觉把他们跟 &&|| 的优先级搞模糊了。 写出了类似下面的代码,而且很久都没发现问题。直到特定的参数触发了报错。

$a = $b or $c;

image 然后,我就不敢再用这个东西了。 不仅 PHP 自己这块容易记混淆,还容易跟 JS 的逻辑运算符记混淆。 为了避免自己再次犯错,现在已经弃坑

lanlin avatar May 14 '19 11:05 lanlin