PHP中的布尔赋值运算符


Boolean assignment operators in PHP

我发现自己经常做这种事情:

$foo = true;
$foo = $foo && false; // bool(false)

使用按位运算符,可以使用&=|=的简写:

$foo = 1;
$foo &= 0; // int(0)

假设10上的逐位运算在功能上等效于truefalse上的布尔运算,我们可以依赖类型转换并执行以下操作:

$foo = true;
$foo &= false; // int(0)
$foo = (bool)$foo; // bool(false)

但这非常难看,并且违背了使用简写赋值语法的目的,因为我们必须使用另一条语句才能将类型恢复为boolean。

我真正想做的是这样的事情:

$foo = true;
$foo &&= false; // bool(false)

&&=||=显然不是有效的算子。所以,我的问题是——是否有其他一些甜蜜的语法,或者可能有一个模糊的核心函数可以作为替代?对于短如$foo的变量,只使用$foo = $foo && false语法并不是什么大不了的事,但具有多维的数组元素和/或对象方法调用可能会使语法变得相当冗长。

在某种程度上,您已经回答了自己的问题:

1和0上的逐位运算在功能上等效于真和假上的布尔运算

请记住,PHP是一种弱类型语言,因此不需要对严格布尔值进行类型转换,因为10等效于truefalse(除了严格相等,请参见下文)。

使用您的示例,考虑以下代码:

$foo = true;
$foo &= false;
if (!$foo) {
  echo 'Bitwise works!';
}
$bar = true;
$bar = $bar && false;
if (!$bar) {
  echo 'Boolean works!';
}
// Output: Bitwise works!Boolean works!

考虑到PHP的隐式类型杂耍、错误的值,除了严格的equatiy,我很难看出&&=||=的这种简写操作在哪里不会产生与&=|=相同的结果。特别是当评估布尔值时。这很可能是PHP中不存在这种人手不足的原因。

更新

一些快速基准测试证明了它们确实是等效的,除了truthy数组/对象:

<?php
$values = array(false, 0, 0.0, "", "0", array(), 12, "string", array(1));
foreach ($values as $value) {
    $bit_test = true;
    $bit_test &= $value;
    $bool_test = true;
    $bool_test = $bool_test && false;
    if ($bit_test != $bool_test) {
        echo 'Difference for: ';
        var_dump($value);
    }
}
// Output:
// Difference for: array(1) {
//  [0]=>
//  int(1)
// }

正如Jason所提到的,位运算符将起作用,并且不需要将结果转换回布尔值,因为PHP已经将其值正确地作为布尔值处理。

如果你想要一个不使用逐位运算符的替代方法,为了可读性,或者如果你想要严格相等,你可以使用这个方法:

function OrOp(&$booleanVar, $conditions)
{
    $booleanVar = $booleanVar && $conditions;
    return $booleanVar;
}

也就是说,你可以改变这个:

$foo = $foo && false;

对此:

OrOp($foo, false);

它还可以在多种条件下工作:

OrOp($foo, $condition1 && $condition2 && $condition3);

Right、&&=||=运算符在PHP中确实缺失,因为位运算符不能用作替换(无强制转换)。

下面是一个您希望返回true但返回false:的示例

$a = true;
$a &= 10; // => returns 0 (false) because 1 & 10 = 0

缺少的&&=运算符将返回true,因为1 && 10=true

$a = true;
$a &&= 10; // => $a would be true