17

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

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

使用位运算符,您可以使用&=and|=简写:

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

鉴于 and 上的按位运算在1功能0上等同于 and 上的布尔运算truefalse我们可以依赖类型转换并执行以下操作:

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

...但这很丑陋并且违背了使用速记赋值语法的目的,因为我们必须使用另一个语句来将类型恢复为布尔值。

我真正想做的是这样的:

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

...但&&=and||=显然不是有效的运算符。所以,我的问题是 - 是否有其他一些含糖的语法或者可能作为替代品的晦涩的核心功能?对于像 一样短的变量,$foo仅使用语法并不是什么大问题$foo = $foo && false,但是具有多个维度的数组元素和/或对象方法调用会使语法变得非常冗长。

4

2 回答 2

5

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

对 1 和 0 的按位运算在功能上等同于对 true 和 false 的布尔运算

请记住,PHP 是一种弱类型语言,因此不必将严格的布尔值类型转换为1and0等价于trueand false(严格相等除外,见下文)。

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

$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 的隐式类型杂耍虚假值以及除了严格相等之外,我很难看出 and 的这种速记操作在哪里&&=不会||=产生与&=and相同的结果|=。特别是在评估布尔值时。这可能是 PHP 中不存在这种速记的原因。

更新

一些快速的基准测试证明这些确实是等价的,除了真实的数组/对象:

<?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)
// }
于 2013-07-09T16:35:44.180 回答
1

正如 Jason 所提到的,按位运算符将起作用,并且没有必要将结果转换回布尔值,因为 PHP 已经将它们的值作为布尔值正确处理。

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

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

这意味着,你可以改变这个:

$foo = $foo && false;

对此:

OrOp($foo, false);

它也适用于多种条件:

OrOp($foo, $condition1 && $condition2 && $condition3);
于 2013-07-09T16:20:02.517 回答