FtD*_*Xw6 15 php syntax boolean-logic syntactic-sugar
我发现自己经常这样做:
$foo = true;
$foo = $foo && false; // bool(false)
Run Code Online (Sandbox Code Playgroud)
使用按位运算符,您可以使用&=
和|=
简写:
$foo = 1;
$foo &= 0; // int(0)
Run Code Online (Sandbox Code Playgroud)
鉴于按位运算1
并且0
在功能上等效于true
和的布尔运算false
,我们可以依赖于类型转换并执行以下操作:
$foo = true;
$foo &= false; // int(0)
$foo = (bool)$foo; // bool(false)
Run Code Online (Sandbox Code Playgroud)
...但是这很丑陋并且违背了使用速记赋值语法的目的,因为我们必须使用另一个语句来将类型返回到布尔值.
我真正想做的是这样的事情:
$foo = true;
$foo &&= false; // bool(false)
Run Code Online (Sandbox Code Playgroud)
......但&&=
和||=
无效的运营商,很明显.所以,我的问题是 - 是否有一些其他含糖的语法或者可能是一个不起眼的核心功能可以作为替身?如果变量尽可能短$foo
,那么使用$foo = $foo && false
语法并不是什么大问题,但是具有多个维度的数组元素和/或对象方法调用会使语法非常冗长.
在某种程度上,您已经回答了自己的问题:
1 和 0 的按位运算在功能上等同于 true 和 false 的布尔运算
请记住,PHP 是一种弱类型语言,因此没有必要对严格布尔值进行类型转换,因为1
和0
等价于true
和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!
Run Code Online (Sandbox Code Playgroud)
鉴于 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)
// }
Run Code Online (Sandbox Code Playgroud)
正如 Jason 提到的,按位运算符可以工作,并且不需要将结果转换回布尔值,因为 PHP 已经正确地将它们的值作为布尔值处理。
如果您想要一个不使用按位运算符的替代方案,为了可读性或者如果您想要严格相等,您可以使用此方法:
function OrOp(&$booleanVar, $conditions)
{
$booleanVar = $booleanVar && $conditions;
return $booleanVar;
}
Run Code Online (Sandbox Code Playgroud)
这意味着,你可以改变这个:
$foo = $foo && false;
Run Code Online (Sandbox Code Playgroud)
对此:
OrOp($foo, false);
Run Code Online (Sandbox Code Playgroud)
它还适用于多种条件:
OrOp($foo, $condition1 && $condition2 && $condition3);
Run Code Online (Sandbox Code Playgroud)