5

我在学校看到一个使用二进制字符串设置权限的系统。

假设 101001 = 41

所以 :

  • 1 可以是第 1 页的权限
  • 2 可以是第 2 页的权限
  • 4可以是第3页的权限
  • 8可以是第4页的权限
  • 16可以是第5页的权限
  • 32可以是第6页的权限

所以假设我得到了上面的二进制字符串(101001)。我可以访问第 1、4 和 6 页。

我怎样才能在 PHP 中做到这一点?假设我在 MySQL 中有一个名为perms存储在 dec 中的字段,因此 101001 将是 41。我怎么知道 41 在 PHP 中等于 1、8 和 32?

谢谢。

4

5 回答 5

13

听起来您在谈论位和位运算符。最简单的设置方法是为每个权限定义常量

const POST   = 1;
const DELETE = 2;
const UPDATE = 4;
const READ   = 8;

一旦你定义了这些,就很容易使用按位运算符进行比较:

$userValue = '1101';

if ($userValue & self::POST) {
  echo 'Can Post';
}

if ($userValue & self::DELETE) {
  echo 'Can Delete';
}

if ($userValue & self::UPDATE) {
  echo 'Can Update';
}

if ($userValue & self::READ) {
  echo 'Can Read';
}

这就是 PHP 自己的常量的工作量。如果您曾经使用类似于E_ALL & E_DEPRECATED实际使用二进制数的方法设置错误报告。

于 2012-05-08T19:07:59.133 回答
3

您可以使用& operator并检查这些标志。

$READ = 8;
$WRITE = 1;
$EXECUTE = 32;
$permissions = 41;
if ($permissions & $READ) {
   // do smth
}
if ($permissions & $WRITE ) {
   // do smth
}
if ($permissions & $EXECUTE ) {
   // do smth
}

让我解释一下。如果您有位 1001 (9)。您只需检查位 (1000) 和 1001。您只需将 $permissions 变量的每一位与位数相乘。结果将是 1000。它可以转换为true值。所以你在这里有旗帜。如果检查第三位(0100),它将导致 0000 和它的false值。所以你在这里没有权限。

于 2012-05-08T19:03:55.393 回答
3

这是一个很好的片段。取自这里http://www.litfuel.net/tutorials/bitwise.htm

<?php
$read = 1;
$write = 2;
$readwrite = 16;
$local_admin = 32;
$global_admin = 64;

$jim = 96;
$mike = 16;

echo "Is Mike Allowed to edit? he has an access level of 16<BR>";
if ($mike & 32) {
    echo 'YES MIKE CAN EDIT';
} else {
    echo 'NO HE CANNOT';
}

echo "<BR><BR>Is Jim Allowed to edit? he has an access level of 96<BR>";
if ($jim & 32) {
    echo 'YES JIM CAN EDIT';
} else {
    echo 'NO HE CANNOT';
}
?>
于 2012-05-08T19:04:10.793 回答
0

这就是二进制的本质——每个数字只有一个 1 和 0 的组合。

PHP 注释中的一个函数decbin

function bindecValues($decimal, $reverse=false, $inverse=false) {
/*
1. This function takes a decimal, converts it to binary and returns the
     decimal values of each individual binary value (a 1) in the binary string.
     You can use larger decimal values if you pass them to the function as a string!
2. The second optional parameter reverses the output.
3. The third optional parameter inverses the binary string, eg 101 becomes 010.
-- darkshad3 at yahoo dot com
*/

    $bin = decbin($decimal);
    if ($inverse) {
        $bin = str_replace("0", "x", $bin);
        $bin = str_replace("1", "0", $bin);
        $bin = str_replace("x", "1", $bin);
    }
    $total = strlen($bin);

    $stock = array();

    for ($i = 0; $i < $total; $i++) {
        if ($bin{$i} != 0) {
            $bin_2 = str_pad($bin{$i}, $total - $i, 0);
            array_push($stock, bindec($bin_2));
        }
    }

    $reverse ? rsort($stock):sort($stock);
    return implode(", ", $stock);
}

用法

$binary_array = bindecValues(41);

这将使binary_array

array(1, 8, 32);
于 2012-05-08T19:03:47.120 回答
0

decbin由于它是二进制和十进制,您可以使用and来回转换它bindec。这只是一个不同的基础来计算......

编辑:按位是甜蜜的,这样做^_^

于 2012-05-08T19:05:15.787 回答