我阅读了以下 Stack Overflow 问题,了解了按位和逻辑之间的区别。
但是,它们都没有解释我应该何时使用按位或逻辑。
我什么时候应该使用按位运算符而不是逻辑运算符,反之亦然?
什么情况下需要一点一点比较?
我不是在问差异,而是在问你需要使用按位运算符时的情况。
我阅读了以下 Stack Overflow 问题,了解了按位和逻辑之间的区别。
但是,它们都没有解释我应该何时使用按位或逻辑。
我什么时候应该使用按位运算符而不是逻辑运算符,反之亦然?
什么情况下需要一点一点比较?
我不是在问差异,而是在问你需要使用按位运算符时的情况。
Bitwise 对 PHP 中的东西很有用,就像其他任何东西一样。
可以同时打开多个状态的值怎么样?
<?php
// since we're setting constant values in base10 we must progressively double
// them since bitwise operations work in base2. you'll see why when we output
// these as binary values below.
const STATE_FOO = 1;
const STATE_BAR = 2;
const STATE_FEZ = 4;
const STATE_BAZ = 8;
// show base2 values of the above constants
echo sprintf("STATE_FOO's base2 value is %08d\n", decbin(STATE_FOO));
echo sprintf("STATE_BAR's base2 value is %08d\n", decbin(STATE_BAR));
echo sprintf("STATE_FEZ's base2 value is %08d\n", decbin(STATE_FEZ));
echo sprintf("STATE_BAZ's base2 value is %08d\n\n", decbin(STATE_BAZ));
// set state to FOO and FEZ
$state = STATE_FOO | STATE_FEZ;
echo sprintf("base10 value of \$state is %s\n", $state);
echo sprintf("base2 value of \$state is %08d\n", decbin($state));
echo sprintf("Does \$state include FOO state? %s\n", (bool)($state & STATE_FOO));
echo sprintf("Does \$state include BAR state? %s\n", (bool)($state & STATE_BAR));
echo sprintf("Does \$state include FEZ state? %s\n", (bool)($state & STATE_FEZ));
echo sprintf("Does \$state include BAZ state? %s\n", (bool)($state & STATE_BAZ));
echo sprintf("Is state equivalent to FOO and FEZ states? %s\n", ($state == (STATE_FOO | STATE_FEZ)));
输出:
STATE_FOO's base2 value is 00000001
STATE_BAR's base2 value is 00000010
STATE_FEZ's base2 value is 00000100
STATE_BAZ's base2 value is 00001000
base10 value of $state is 5
base2 value of $state is 00000101
Does $state include FOO state? 1
Does $state include BAR state?
Does $state include FEZ state? 1
Does $state include BAZ state?
Is state equivalent to FOO and FEZ states? 1
忘记已经在你脑海中的东西。
好的,现在假设您有一些不同的角色:admin、user和guest。
和一些不同的权限:读取、写入和删除
让我们为权限和角色创建一些位掩码。位掩码是可用于操作或读取某种标志的位序列。如下所示:
// flags bitmasks
$read = 1; // 0001
$write = 2; // 0010
$delete = 4; // 0100
$admin = $read | $write | $delete; // 0001 | 0010 | 0100 => 0111
$user = $read | $write; // 0001 | 0010 => 0011
$guest = $read; // 0001 => 0001
注意 1、2、4。这必须提高为 double。否则,它可能会给您带来一些尴尬的结果。
忘记评论的事情。这些只是各个权限和角色的位序列(或位掩码)。
现在让我们创建一个方便的函数,该函数可用于检查特定角色的特定权限。
function isAllowed($role, $permissison) {
return $role & $permissison ? true : false;
}
我们完了。让我们检查所有 3 个角色的$delete权限:
var_dump(isAllowed($admin, $delete)); // bool(true)
var_dump(isAllowed($user, $delete)); // bool(false)
var_dump(isAllowed($guest, $delete)); // bool(false)
那么为什么是按位运算呢?总之,按位运算更快、更简洁、更易于维护。否则,对于复杂的应用程序,使用按位运算总是有效的。
按位|
和&
逻辑||
和&&
完全不同。
位运算符对两个数字的位执行运算并返回结果。这意味着这不是一个是或不是的事情。如果在条件语句中使用它们,它们通常被用作逻辑比较的一部分。例如:
if ($x & 2 == 2) {
// The 2^1 bit is set in the number $x
}
逻辑运算符比较两个(或更多)条件/表达式并返回真或假。您最常在条件语句中使用它们,例如if
and while
。例如:
if ($either_this || $or_this) {
// Either expression was true
}
位运算符专门用于二进制值表示的情况。
echo '0110011010' & '0101001001';
//0100001000
逻辑运算符最适合用于比较,并且在AND
和运算的情况下比按位运算符快一点XOR
。
if(func1() && func2())
如果func1()
返回 false 它不会打扰调用func2()
if(func1() & func2())
无论返回值如何,都将调用这两个函数。
在大多数情况下,您可能希望使用逻辑运算符。它们用于组合逻辑条件,通常用于控制程序流程,例如($isAlive && $wantsToEat)
.
当您想要对整数的底层二进制表示逐位执行操作时,将使用按位运算符。例如 (5 & 3) == 7
。正如其他人所建议的那样,在倾向于用 PHP 编写的那种应用程序中,通常没有太多的需求(尽管有较低级别的语言,如 C)。
他们是两个截然不同的运营商。
当您希望两个条件同时为真时,您可以使用逻辑&&
. 例如,我只想打印出“生日快乐”,只有当这个人的生日是今天&& 他们的账户里有钱。每当我们想要执行两个或多个条件的组合时都会使用它,主要是在 if 语句和循环条件中(尽管不是唯一的)。
当您想要执行按位运算(这在日常 PHP 编程中更为罕见)时,您可以使用按位&
. 这种情况要少得多,而且您可能正在执行按位屏蔽(尽管我对此表示怀疑),因此您可能只想要两个整数都表示的结果,在这种情况下您可以说newAttribute = attribute1 & attribute2;
.
好吧,假设有$x = (false && some_function());
,这里的值$x
将在不调用的情况下设置,some_function()
因为第一个值为 FALSE。
但是,如果您仍然需要调用该函数怎么办?使用$x = (false & some_function());
.
换句话说,&
使用比 && 更多的处理,只是因为 && 不会遍历所有值来检查它们。如果它发现一个值为假,它将返回它,而不是查看其他值。
在逻辑运算中,使用&&
运算符,因为它用于返回逻辑运算值,其中&
用于设置值,在if
语句中它将始终返回true。