How to test PHP parameter input bitwise functions

Sometimes in programming, they allow you to bind parameters to one input variable of a function, just like the second input variable below:

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

      

PHP calls this single pipe symbol (|)

bitwise OR

. How do I add something inside foo()

to check $vFlags

to see what flags have been set?

+3


source to share


3 answers


I think you will find that flags like this are usually defined as authority 2, for example:

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

      

As you rightly said, they can be combined using the bitwise OR operator:



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

      

To check these flags inside your function, you need to use the bitwise AND operator like this:

function foo($sFile, $vFlags) {
  if ($vFlags & FLAGA) {
    // FLAGA was set
  }
  if ($vFlags & FLAGB) {
    // FLAGB was set
  }
  //// etc...
}

      

+4


source


The "flags" parameter will be referred to as the bitmask. One byte contains 8 bits that are either set or not set. You simply assign your meaning to each bit; if set, it means yes for that particular bit, otherwise no.

So, you need to start by defining your flags with the correct values ​​that set the correct bits; just arbitrary numbers won't be concatenated into correct paths:

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

      



Considering the above, FLAGB | FLAGD

creates a bit mask with the second and fourth bits ( 00001010

). To do this, you need to slightly improve the conversion between base 2 (binary) and base 10 (decimal) for this.

To test this, you use &

:

$flags = FLAGB | FLAGD;

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

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

..

      

+2


source


You need a bitwise operator 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);

      

DEMO

However, bitwise operations necessarily work in binary terms, where each bit is a power of 2. Thus, you generally want to define flags in powers of 2, as in

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

      

Otherwise, imagine this scenario:

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

      

If you have a value of 40 for $vFlags

, you cannot determine which flags are set; it can be any of the following:

FLAGA & FLAGB
FLAGA & FLAGB & FLAGC
FLAGA & FLAGC
FLAGB & FLAGC
FLAGC

      

0


source







All Articles