PHP中的位操作和MySQL检索

Bri*_*ian 3 php mysql

我试图优化我的mysql表一点点,以便有一个稍微更易于管理的表.我想将用户权限存储在位字段中.

例如,用户权限可能是0110(我的用户权限越来越多,所以这个长度可能会长一些)

该示例可能对应于以下内容:

0:用户无法在网站上发布新闻1:用户可以在网站上发布新文章1:用户可以编辑网站上的任何文章0:用户无法从网站上删除文章等(其他权限)

如果我将它存储在mysql位字段中.我怎样才能在PHP中操作它?

例如,在PHP中有一种简单的方法来获取第3位并查看它是0还是1?

有没有一种简单的方法可以将第3位设置为0或1?

Mat*_*ger 7

您是否考虑将权限存储为整数,每个权限都是二进制值(即1,2,4,8,16),并将所有权限加在一起.然后,您可以使用&运算符检查他们是否具有给定的权限

像这样:

if ($accessLevel & $userPermissions) 
Run Code Online (Sandbox Code Playgroud)

这为您提供了比存储二进制数更有用的系统


根据评论中的要求,提供更多信息.

您可以将users表设置为具有整数字段来存储您的权限.您的每个权限级别都将具有二进制位的二进制倍数(此处不知道正确的术语).例如:

Read - 1
Edit - 2
Create - 4
Delete - 8
Run Code Online (Sandbox Code Playgroud)

等等,尽可能多.要创建用户权限级别,请将这些值或值组合在一起.让我们假设上面的级别作为静态值存储在一个类中,您可以像这样创建它:

$newUser->Permissions = Permissions::Read | Permissions::Create;
Run Code Online (Sandbox Code Playgroud)

这为您提供了可以阅读和创建但不能编辑或删除的用户.

要检查用户是否有权执行操作,请使用AND:

if ($newUser->Permissions & Permissions::Read) {
    echo 'You can do this!';
}  else {
    echo 'You can't this!';
}
Run Code Online (Sandbox Code Playgroud)

这为您提供了一个简单的数据库字段,它可以像您实际需要的那样扩展,并且易于使用检查和更改.您可能还需要考虑在另一个表等中存储权限级别,具体取决于您可能需要的自定义级别.


Pas*_*TIN 5

您可以使用按位运算符.

例如 :

$bits = bindec('0110');
var_dump($bits & bindec('0100'));
Run Code Online (Sandbox Code Playgroud)

将得到"4" (即非零 - 你可以认为是"ok"),因为设置了第三位$bits.

而且:

$bits = bindec('0010');
var_dump($bits & bindec('0100'));
Run Code Online (Sandbox Code Playgroud)

会得到0 - 因为$bits没有设置第三位.


当然,不需要bindec每次都打电话- 我只是在这里使用它来使事情更容易阅读; 我的第一个例子可以改写成这样的东西:

$bits = bindec('0110');
var_dump($bits & 1<<2);
Run Code Online (Sandbox Code Playgroud)


为了使代码更容易理解,不要使用这样的魔术值,而是使用一些常量; 例如 :

define('PERMISSION_TO_DO_X', 1);
define('PERMISSION_TO_DO_Y', 1<<1);
define('PERMISSION_TO_DO_Z', 1<<2);
Run Code Online (Sandbox Code Playgroud)

并使用它们:

$bits = bindec('0110');
if ($bits & PERMISSION_TO_DO_X) {
    echo "OK to do X<br />";
}
if ($bits & PERMISSION_TO_DO_Y) {
    echo "OK to do Y<br />";
}
if ($bits & PERMISSION_TO_DO_Z) {
    echo "OK to do Z<br />";
}
Run Code Online (Sandbox Code Playgroud)

在这里,你可以得到那种输出:

OK to do Y
OK to do Z
Run Code Online (Sandbox Code Playgroud)

因为:

  • 最右边的位是0(许可X未被授予)
  • 第二位(从右侧开始)为1:授予Y权限
  • 第三位(仍然始终从右侧开始)为1:授予Z权限