为什么我应该使用按位/位在PHP?
-
21-09-2019 - |
题
我正在用户的作用/许可权系统在PHP为一个脚本。
下面是一个密码使用的一位方法的权限,我发现在phpbuilder.com.
下面的那一部分是一个更简单的版本w3hich能做到基本上相同的事情没有位的一部分。
许多人建议用比经营者和诸如对设置和其他东西在PHP,我从来没有理解为什么虽然。在代码下面有没有 任何好处 从使用第一代而不是第二次吗?
<?php
/**
* Correct the variables stored in array.
* @param integer $mask Integer of the bit
* @return array
*/
function bitMask($mask = 0) {
$return = array();
while ($mask > 0) {
for($i = 0, $n = 0; $i <= $mask; $i = 1 * pow(2, $n), $n++) {
$end = $i;
}
$return[] = $end;
$mask = $mask - $end;
}
sort($return);
return $return;
}
define('PERMISSION_DENIED', 0);
define('PERMISSION_READ', 1);
define('PERMISSION_ADD', 2);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 8);
//run function
// this value would be pulled from a user's setting mysql table
$_ARR_permission = bitMask('5');
if(in_array(PERMISSION_READ, $_ARR_permission)) {
echo 'Access granted.';
}else {
echo 'Access denied.';
}
?>
非位版本
<?PHP
/*
NON bitwise method
*/
// this value would be pulled from a user's setting mysql table
$user_permission_level = 4;
if($user_permission_level === 4) {
echo 'Access granted.';
}else {
echo 'Access denied.';
}
?>
解决方案
为什么不这样做?
define('PERMISSION_DENIED', 0);
define('PERMISSION_READ', 1);
define('PERMISSION_ADD', 2);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 8);
//run function
// this value would be pulled from a user's setting mysql table
$_ARR_permission = 5;
if($_ARR_permission & PERMISSION_READ) {
echo 'Access granted.';
}else {
echo 'Access denied.';
}
您还可以,如果你使用的比特创造大量权限的任意组合...
$read_only = PERMISSION_READ;
$read_delete = PERMISSION_READ | PERMISSION_DELETE;
$full_rights = PERMISSION_DENIED | PERMISSION_READ | PERMISSION_ADD | PERMISSION_UPDATE | PERMISSION_DELETE;
//manipulating permissions is easy...
$myrights = PERMISSION_READ;
$myrights |= PERMISSION_UPDATE; // add Update permission to my rights
其他提示
第一个允许人们有很多的权限 - 例如读/添加/更新。第二个例子中,用户刚刚PERMISSION_UPDATE
。
按位通过测试比特的真值测试作品。
例如,二进制序列10010
将识别用户与PERMISSION_DELETE
和PERMISSION_READ
(比特识别PERMISSION_READ
为2列,位标识PERMISSION_DELETE
是16列),10010
二进制是十进制18(16 + 2 = 18)。你的第二个代码示例不允许你做那种测试。你可以做大于式的检查,但它假定每个人都PERMISSION_DELETE
也应该有PERMISSION_UPDATE
,这可能不是一个有效的假设。
也许这只是因为我不用位掩码经常,但我发现在一种语言如PHP在开发人员的工作效率和代码阅读是更为重要的不是速度或存储器的使用(在一定限度内,很明显),就没有真正的理由使用bitmasking.
为什么不能,而不是创建一个类轨道的东西喜欢的权限,并登录用户,等等?让我们叫它认证。然后,如果你想检查一个用户拥有的权限,您可以创建一个方法必.例如,
if(Auth::logged_in() && Auth::currentUser()->hasPermission('read'))
//user can read
然后如果你想要检查它们是否具有的一些组合的权限:
if(Auth::logged_in() && Auth::currentUser()->hasAllPermissions('read', 'write'))
//user can read, and write
或者如果你想要检查它们是否具有任何一组特定的权限:
if(Auth::logged_in() && Auth::currentUser()->hasAnyPermissions('read', 'write'))
//user can read, or write
当然,它可能不是一个糟糕的想法定义常数,如PERMISSION_READ,你可以,只是定义是string"读",等等。
我找到这种办法更易于读取比位掩码的,因为该方法的名称告诉你到底是什么是您要找的内容。
修改:重读的问题,它看起来像用户的权限来了一个位域从数据库回来。如果是这样的话,你将不得不使用位运算符。谁的权限在数据库中的用户是5
有PERMISSION_READ
和PERMISSION_DENIED
因为(PERMISSION_READ & 5) != 0
和(PERMISSION_DENIED & 5) != 0
。他不会有PERMISSION_ADD
,因为(PERMISSION_ADD & 5) == 0
这是否有意义?在您按位举例而言,所有复杂的东西看起来是不必要的。
如果您不完全了解位操作,那么就不要使用它们。这只会导致很多麻烦。如果你习惯使用它们,然后用它们,你觉得他们是合适的。您(或谁写的逐位码)似乎并没有完全掌握位操作。有几个问题与它一样的事实pow()
功能时,会否定任何形式的性能优势。 (相反pow(2, $n)
的,应使用按位1 << $n
,例如。)
这就是说,似乎代码的两片不做同样的事情。
尝试使用的是什么bit.class.php 在 http://code.google.com/p/samstyle-php-framework/source/browse/trunk/class/bit.class.php
检查针对特定位:
<?php
define('PERMISSION_DENIED', 1);
define('PERMISSION_READ', 2);
define('PERMISSION_ADD', 3);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 5);
if(bit::query($permission,PERMISSION_DENIED)){
echo 'Your permission is denied';
exit();
}else{
// so on
}
?>
并打开和关闭:
<?php
$permissions = 8;
bit::toggle(&$permissions,PERMISSION_DENIED);
var_dump($permissions); // outputs int(9)
?>
的这个问题是,如果是PERMISSION_READ掩模本身
if($ARR_permission & PERMISSION_READ) {
echo 'Access granted.';
}else {
echo 'Access denied.';
然后对于 0101 - $ rightWeHave 0011 - $ rightWeRequire
有授权的访问,我们可能不希望因此它应该是
if (($rightWeHave & $rightWeRequire) == $rightWeRequire) {
echo 'access granted';
}
所以现在对于
0101 0011
结果是
0001,以便访问不被许可,因为它不等于0011
但
1101 0101
它是确定作为结果是0101
<强>脚本检查哪个掩模已在小数集。也许有人会需要它:
<?php
$max = 1073741824;
$series = array(0);
$x = 1;
$input = $argv[1]; # from command line eg.'12345': php script.php 12345
$sum = 0;
# generates all bitmasks (with $max)
while ($x <= $max) {
$series[] = $x;
$x = $x * 2;
}
# show what bitmask has been set in '$argv[1]'
foreach ($series as $value) {
if ($value & $input) {
$sum += $value;
echo "$value - SET,\n";
} else {
echo "$value\n";
}
}
# sum of set masks
echo "\nSum of set masks: $sum\n\n";
输出(PHP maskChecker.php 123):
0
1 - SET,
2 - SET,
4
8 - SET,
16 - SET,
32 - SET,
64 - SET,
128
256
512
1024
2048
4096
8192
(...)
Sum of set mask: 123
我想第一个例子给你什么权限的用户拥有更多的控制权。在第二个,你只需要一个用户“级别”;想必更高级别继承授予“低层次”用户的所有权限,所以你没有这样的精细控制。
另外,如果我已经正确理解的,线
if($user_permission_level === 4)
意味着只有用户的究竟的权限级别4有机会获得行动 - 你一定会要检查用户拥有的至少的那个水平?