3

有时在编程中,它们允许将参数链接到单个函数输入变量中,如下面的第二个输入变量:

define('FLAGA',40);
define('FLAGB',10);
define('FLAGC',3);
function foo($sFile, $vFlags) {
  // do something
}
foo('test.txt',FLAGA | FLAGB | FLAGC);

PHP 将此单管道字符(|)称为按位OR运算符。我现在如何在里面添加一些东西foo()来测试$vFlags看看设置了哪些标志?

4

3 回答 3

5

我想你会发现像这样的标志通常被定义为 2 的幂,例如:

define('FLAGA',1);
define('FLAGB',2);
define('FLAGC',4); /* then 8, 16, 32, etc... */

正如您正确指出的那样,这些可以通过使用按位 OR 运算符组合:

foo('test.txt',FLAGA | FLAGB | FLAGC);

要在函数中测试这些标志,您需要使用按位 AND 运算符,如下所示:

function foo($sFile, $vFlags) {
  if ($vFlags & FLAGA) {
    // FLAGA was set
  }
  if ($vFlags & FLAGB) {
    // FLAGB was set
  }
  //// etc...
}
于 2014-12-19T05:50:53.230 回答
3

“标志”参数将被称为位掩码。单个字节包含 8 位,这些位设置或未设置。你只需为每一点赋予你自己的意义;如果已设置,则表示该特定位的yes,否则no

因此,您需要首先使用设置正确位的正确值定义您的标志;只是任意数字不会以正确的方式组合在一起:

define('FLAGA', 1);  // 00000001
define('FLAGB', 2);  // 00000010
define('FLAGC', 4);  // 00000100
define('FLAGD', 8);  // 00001000

鉴于上述情况,FLAGB | FLAGD创建一个位掩码,其中设置了第二个和第四个位 ( 00001010)。为此,您需要在以 2 为底(二进制)和以 10 为底(十进制)之间进行转换。

要对此进行测试,请使用&

$flags = FLAGB | FLAGD;

if ($flags & FLAGA) {
    echo 'flag A is set';
}

if ($flags & FLAGB) {
    echo 'flag B is set';
}

..
于 2014-12-19T05:53:09.347 回答
0

您需要按位运算AND&

define('FLAGA',40);
define('FLAGB',10);
define('FLAGC',3);

function foo($sFile, $vFlags) {
  if ($vFlags & FLAGA) {
    echo "FLAGA is set\n";
  }
  if ($vFlags & FLAGB) {
    echo "FLAGB is set\n";
  }
  if ($vFlags & FLAGC) {
    echo "FLAGC is set\n";
  }
}
foo('test.txt',FLAGA | FLAGB | FLAGC);

演示

也就是说,按位运算必须以二进制形式工作,其中每个位代表 2 的幂。因此,您通常会希望以 2 的幂定义标志,如

define('FLAGA',1);
define('FLAGB',2);
define('FLAGC',4);
define('FLAGD',8); // etc.

否则,想象一下这种情况:

define('FLAGA',8);
define('FLAGB',32);
define('FLAGC',40);

如果你有一个值 40 $vFlags,你就无法知道设置了哪些标志;它可以是以下任何一种:

FLAGA & FLAGB
FLAGA & FLAGB & FLAGC
FLAGA & FLAGC
FLAGB & FLAGC
FLAGC
于 2014-12-19T05:55:18.593 回答