How to implement a bitmask in php?

Viewed 33547

I'm not sure if bitmask is the correct term. Let me explain:

In php, the error_reporting function can be called multiple ways:

// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Reporting E_NOTICE can be good too (to report uninitialized
// variables or catch variable name misspellings ...)
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);

// Report all errors except E_NOTICE
// This is the default value set in php.ini
error_reporting(E_ALL ^ E_NOTICE);

I got the term bitmask from the php.net page here

Anyway the point of this is, I have implemented a SIMPLE method called ls which returns the contents of a directory.

This function takes 3 args... ( $include_hidden = false, $return_absolute = false, $ext = false )

So when i call the function, i set how i want the results. Whether i want the results to return hidden directories, whether i want basenames only etc.

so when i call the function i'm writing

ls(true, false, true)
ls(false, false, true)
ls(true, true, true)
etc...

I thought it would be much more readable if i could just flag how i want the data returned?

so something like:

ls( INCLUDE_HIDDEN | HIDE_EXTS );
ls( SHOW_ABSOLUTE_PATHS | HIDE_EXTS );

etc...

How would i implement this in terms of testing which flags have been called?

4 Answers

I had an API I was working with - the documentation was pretty thin. It was giving us a single integer and said:

"Information is encoded in these values as a bit field. Bit fields work by storing multiple true/false values in the same integer, instead of having multiple integers for each value. To look up a value in a bitfield, you'll want to make use of Bit Masks."

Bit     Decimal Value    Setting
0       1                Display
1       2                Sell
2       4                Kiosk Display
3       8                No Passes
4       16               Dolby Digital
5       32               THX
6       64               DLP
[etc]

I figured out how to solve it based on the other answers here, and though I would share the function I came up with.

I ended up writing this function:

<?php
function bitmap_decode( $label_array, $value, $return_item ) {
    $label_array = array_flip( $label_array ); // swap the keys and values
    $i = $label_array[ $return_item ]; // get the decimal key value for the item on the list
    $i =  2**$i; // use 2 to the nth power to get the decimal bitmap value for the item
    return $value & $i ? 1 : 0; // use the & operator to determine if the value is true or false. return 1 or 0 accordingly
}

... which would parse out the values

$info1 = array(
    'Display',
    'Sell',
    'Kiosk Display',
    'No Passes',
    'Dolby Digital',
    'THX',
    'DLP',
);


$api_value = 5;
echo bitmap_decode( $info1, $api_value, 'Sell' ); // 0

$api_value = 35;
echo bitmap_decode( $info1, $api_value, 'Sell' ); // 1

And then we can do the opposite - encode the values without having to think about any non-binary numbers or anything like that:

function bitmap_encode( $items, $label_array ) {
    $return = 0;
    $label_array = array_flip( $label_array ); // swap the keys and values
    foreach ( $items as $item ) {
        $i = $label_array[ $item ]; // get the decimal key value for the item on the list
        $i = 2**$i; // use 2 to the nth power to get the decimal bitmap value for the item
        $return += $i; // add $i to the return value
    }
    return $return;
}

// set these flags as true
$flags = array( 'Display', 'Sell', 'THX' );
echo bitmap_encode( $flags, $info1 ); // 35

I know this does not precisely answer the OP question, but it's another approach to making a bitmask system in PHP.

Related