PHP Bitwise compare values from database with an array

落爺英雄遲暮 提交于 2021-02-11 12:32:04

问题


Actually i would like to compare some values in a table with an array and output the key with has equal value of the array. Problem is: the values in the database are bitwise if i am right. Not sure if it is the right explanation in english.

Example: and here some example values form the table 1,65,2081,2145,18497,32769 65 contains 64 which is "UR_LEAD" and 1 which is "UR_SWP"

Here the array which i would like to compare with:

$userrights_array = array(
"UR_SWP"           => 1,
"UR_BUHA"          => 2,
"UR_AZ"            => 4,
"UR_SA"            => 8,
"UR_FIDI"          => 16,
"UR_ADMIN"         => 32,
"UR_LEAD"          => 64,
"UR_AZ_EVENT"      => 128,
"UR_SA_COMPLIANCE" => 256,
"UR_CH"            => 512,
"UR_USERMOD"       => 1024,
"UR_SWP_GL"        => 2048,
"UR_MEDB"          => 4096,
"UR_SWP_GP"        => 8192,
"UR_STAFF_DEPT"    => 16384,
"UR_MEET_KEYUSER"  => 32768,
"UR_MEET_ADMIN"    => 65536
);

Here the example to loop through the array and actually a fakeresult from the database to simplyfy the code.

$fakerow = 256;
foreach ($userrights_array as $key => $value) {
  if ($value == $fakerow) {
    print_r($key);
  }
};

What i need now is a solution to not just print out the value of the database but do an operation that compares the value from the array with the one in the database and check which fits for example into 65.

Guess i have to do the comparison in the if section but no idea how to.

Output should be like "UR_SWP" + "UR_LEAD"

The actual result in my form looks like this:


回答1:


If you want to print out permissions in words, you can first create a map of values with permissions in text using an array_flip(). Key point here is to collect permissions whose bit is set as 1 in the current permission.

Now, just convert the current permission value at hand to binary and collect the appropriate permission for a particular power of 2 and print out the result.

<?php

$userrights_array = array(
    "UR_SWP"           => 1,
    "UR_BUHA"          => 2,
    "UR_AZ"            => 4,
    "UR_SA"            => 8,
    "UR_FIDI"          => 16,
    "UR_ADMIN"         => 32,
    "UR_LEAD"          => 64,
    "UR_AZ_EVENT"      => 128,
    "UR_SA_COMPLIANCE" => 256,
    "UR_CH"            => 512,
    "UR_USERMOD"       => 1024,
    "UR_SWP_GL"        => 2048,
    "UR_MEDB"          => 4096,
    "UR_SWP_GP"        => 8192,
    "UR_STAFF_DEPT"    => 16384,
    "UR_MEET_KEYUSER"  => 32768,
    "UR_MEET_ADMIN"    => 65536
);

$userrights_array_flipped = array_flip($userrights_array);

foreach([1,65,2081,2145,18497,32769] as $val){
    $pow_2 = 1;
    $rights = [];
    while($val > 0){
        $d = $val % 2;
        if($d == 1 && isset($userrights_array_flipped[$pow_2])){
            $rights[] = $userrights_array_flipped[$pow_2];
        }
        $pow_2 <<= 1;
        $val >>= 1;
    }
    
    echo implode(",",$rights),PHP_EOL;
} 



回答2:


A "Bitwise AND" (&) operator is an option:

<?php
$userrights = array(
    "UR_SWP"           => 1,
    "UR_BUHA"          => 2,
    "UR_AZ"            => 4,
    "UR_SA"            => 8,
    "UR_FIDI"          => 16,
    "UR_ADMIN"         => 32,
    "UR_LEAD"          => 64,
    "UR_AZ_EVENT"      => 128,
    "UR_SA_COMPLIANCE" => 256,
    "UR_CH"            => 512,
    "UR_USERMOD"       => 1024,
    "UR_SWP_GL"        => 2048,
    "UR_MEDB"          => 4096,
    "UR_SWP_GP"        => 8192,
    "UR_STAFF_DEPT"    => 16384,
    "UR_MEET_KEYUSER"  => 32768,
    "UR_MEET_ADMIN"    => 65536
);
$rows = array(1, 65, 2081, 2145, 18497, 32769);

foreach ($rows as $row) {
    echo $row.": ";
    foreach ($userrights as $key => $userright) {
        if ($userright & $row) {
            echo $key.", ";
        }
    };
    echo "<br>";
}
?>

If you want to store the results in a string variable or an array, this may help:

<?php
...

// Store the output as a text
$output = "";
foreach ($rows as $row) {
    $output .= ($output === "" ? "" : ", ");
    foreach ($userrights as $key => $userright) {
        if ($userright & $row) {
            $output .= ($output === "" ? "" : " ") . $key;
        }
    };
}
echo $output;
echo "<br>";

// Store the output as an array
$output = array();
foreach ($rows as $row) {
    $s = "";
    foreach ($userrights as $key => $userright) {
        if ($userright & $row) {
            $s .= ($s === "" ? "" : " ") . $key;
        }
    };
    $output[] = $s;
}
echo print_r($output, true);
echo "<br>";
?>

Results:

1: UR_SWP,
65: UR_SWP, UR_LEAD,
2081: UR_SWP, UR_ADMIN, UR_SWP_GL,
2145: UR_SWP, UR_ADMIN, UR_LEAD, UR_SWP_GL,
18497: UR_SWP, UR_LEAD, UR_SWP_GL, UR_STAFF_DEPT,
32769: UR_SWP, UR_MEET_KEYUSER,

UR_SWP, UR_SWP UR_LEAD, UR_SWP UR_ADMIN UR_SWP_GL, UR_SWP UR_ADMIN UR_LEAD UR_SWP_GL, UR_SWP UR_LEAD UR_SWP_GL UR_STAFF_DEPT, UR_SWP UR_MEET_KEYUSER

Array ( 
   [0] => UR_SWP 
   [1] => UR_SWP UR_LEAD 
   [2] => UR_SWP UR_ADMIN UR_SWP_GL 
   [3] => UR_SWP UR_ADMIN UR_LEAD UR_SWP_GL 
   [4] => UR_SWP UR_LEAD UR_SWP_GL UR_STAFF_DEPT 
   [5] => UR_SWP UR_MEET_KEYUSER 
)


来源:https://stackoverflow.com/questions/65920578/php-bitwise-compare-values-from-database-with-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!