简体   繁体   English

PHP中的位操作和MySQL检索

[英]Bit Manipulation and MySQL Retrieval in PHP

I am trying to optimize my mysql table a little bit in order to have a slightly more manageable table. 我试图优化我的mysql表一点点,以便有一个稍微更易于管理的表。 I would like to store user permissions in a bit field. 我想将用户权限存储在位字段中。

For example, a users permissions could be 0110 (I have a growing number of user permissions, so the length of this could be a bit longer) 例如,用户权限可能是0110(我的用户权限越来越多,所以这个长度可能会长一些)

The example might correspond to the following: 该示例可能对应于以下内容:

0: User cannot post news items on the website 1: User can post new articles on the website 1: User can edit any article on the website 0: User cannot remove articles from the website etc. (for other permissions) 0:用户无法在网站上发布新闻1:用户可以在网站上发布新文章1:用户可以编辑网站上的任何文章0:用户无法从网站上删除文章等(其他权限)

If I have this stored in a mysql bit field. 如果我将它存储在mysql位字段中。 How can I manipulate this in PHP? 我怎样才能在PHP中操作它?

For example, in PHP is there an easy way to get the 3rd bit and see if it is a 0 or a 1? 例如,在PHP中有一种简单的方法来获取第3位并查看它是0还是1?

Is there an easy way to set the 3rd bit to be a 0 or a 1? 有没有一种简单的方法可以将第3位设置为0或1?

Have you considered storing your permissions as an integer, with each permission a binary value (ie, 1,2,4,8,16), and you add together all their permissions. 您是否考虑将权限存储为整数,每个权限都是二进制值(即1,2,4,8,16),并将所有权限加在一起。 You can then check if they have a given permission using the & operator 然后,您可以使用&运算符检查他们是否具有给定的权限

Like so: 像这样:

if ($accessLevel & $userPermissions) 

That gives you a much more usable system than storing a binary number 这为您提供了比存储二进制数更有用的系统


As requested in comments, a little more information. 根据评论中的要求,提供更多信息。

You would set up your users table to have an integer field to store your permissions. 您可以将users表设置为具有整数字段来存储您的权限。 Each of your permission levels would have a binary multiple (don't know the correct term here) that corresponds with the value of a binary bit. 您的每个权限级别都将具有二进制位的二进制倍数(此处不知道正确的术语)。 For example: 例如:

Read - 1
Edit - 2
Create - 4
Delete - 8

And so on, as many as required. 等等,尽可能多。 In order to create a users permission level, you OR the values together. 要创建用户权限级别,请将这些值或值组合在一起。 Let's assume the above levels are stored in a class as static values, you would create it like so: 让我们假设上面的级别作为静态值存储在一个类中,您可以像这样创建它:

$newUser->Permissions = Permissions::Read | Permissions::Create;

Which gives you a user that can read and create, but not edit or delete. 这为您提供了可以阅读和创建但不能编辑或删除的用户。

To check if a user has permission to perform an action, you use AND: 要检查用户是否有权执行操作,请使用AND:

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

This gives you one simple database field, that's as extendible as you'll realistically need, and simple to use checks and changes. 这为您提供了一个简单的数据库字段,它可以像您实际需要的那样扩展,并且易于使用检查和更改。 You might also want to consider storing permission levels in another table, etc, depending on what level of customization you might need. 您可能还需要考虑在另一个表等中存储权限级别,具体取决于您可能需要的自定义级别。

You can use bitwise operators . 您可以使用按位运算符

For instance : 例如 :

$bits = bindec('0110');
var_dump($bits & bindec('0100'));

Will get you "4" (ie non-zero -- which you can consider as "ok") , as the third bit in $bits is set. 将得到“4” (即非零 - 你可以认为是“ok”) ,因为$bits的第三$bits被设置。

And : 而且:

$bits = bindec('0010');
var_dump($bits & bindec('0100'));

Will get you 0 -- as the third bit in $bits is not set. 会得到0 - 因为$bits的第三位未设置。


Of course, no need to call bindec each time -- I just used it here to make things easier to read ; 当然,每次都不需要调用bindec - 我只是在这里使用它来使事情更容易阅读; my first example could be rewritten as something like this : 我的第一个例子可以改写成这样的东西:

$bits = bindec('0110');
var_dump($bits & 1<<2);


And to make to code easier to understand, don't use such magic values, but use some constants ; 为了使代码更容易理解,不要使用这样的魔术值,而是使用一些常量; for instance : 例如 :

define('PERMISSION_TO_DO_X', 1);
define('PERMISSION_TO_DO_Y', 1<<1);
define('PERMISSION_TO_DO_Z', 1<<2);

And to use them : 并使用它们:

$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 />";
}

Which, here, gets you that kind of output : 在这里,你可以得到那种输出:

OK to do Y
OK to do Z

Because : 因为:

  • the right-most bit is 0 (permission X not granted) 最右边的位是0(许可X未被授予)
  • the second bit (starting from the right) is 1 : permission Y is granted 第二位(从右侧开始)为1:授予Y权限
  • the third bit (still and always starting from the right) is 1 : permission Z granted 第三位(仍然始终从右侧开始)为1:授予Z权限

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM