PHP 中的人类可读逻辑权限
Human readable logical permissions in PHP
所以我有一个登录系统,我使用整数列存储用户权限,该列将填充相应的权限编号。我这样做是为了轻松存储多个权限,并保存数据库查询。
所以,这些是我的权限:
create_user = 1
delete_user = 2
edit_user = 4
拥有所有这些权限的用户将拥有权限整数值 7 (1+2+4)。但是,我需要以人类可读的方式呈现用户的权限。
所以我需要做的是再次将 7 解构为这三个数字,最好是用逗号分隔的字符串 (1,2,4
) 但我不能来想出一个函数来做到这一点。
更新:我想这样做是因为我将获取这些整数并根据它们的值转换它们,这样最终用户就可以清楚地看到权限是什么。因此,1,2,4
将变为 Create User,Delete User, Edit User
。
你们有什么智慧吗?
像 @splash58 建议的那样,使用单个 & 符号进行二进制比较。
$permission = 7;
if ($permission & 1 == 1) {
// user has "create_user" permissions
}
if ($permission & 2 == 2) {
// user has "delete_user" permissions
}
if ($permission & 4 == 4) {
// user has "edit_user" permissions
}
大多数使用这种技术进行权限管理的系统都会尝试至少定义人类可读的常量,以防万一您需要更改整数:
define('CREATE_USER', 1);
define('DELETE_USER', 2);
define('EDIT_USER', 4);
$permission = 7;
if ($permission & CREATE_USER == CREATE_USER) {
// user has "create_user" permissions
}
我过去使用过类似类型的授权系统,并且我总是创建一个函数,我可以调用它来检查用户是否具有特定权限,无论我需要放置一些受限的地方 link或检查他们是否被允许查看特定页面:
/**
* Checks whether a user's rights contains a particular permission
*
* @var int $rights sum of a user's rights
* @var int $permission permission to check for
* @return bool
*/
function has_permission($rights, $permission) {
return ($rights & $permission == $permission);
}
通过使用常量,您可以以非常易读的方式调用它:
$permission = 7;
if (has_permission($permission, CREATE_USER)) {
// show the button to create a new user
}
如果您确实需要完全解构用户的权限(例如,您需要获取用户拥有的所有权限的数组),我会将所有可用权限转储到一个数组中并创建一个循环遍历它们的函数:
/**
* Returns an array of all permissions a user has
*
* @var int $rights sum of a user's rights
* @var int[] $permissions list of all known permissions
* @return int[]
*/
function get_permissions($rights, $permissions) {
$user_permissions = array();
foreach ($permissions as $permission) {
if ($rights & $permission == $permission) {
$user_permissions[] = $permission;
}
}
return $user_permissions;
}
$permissions = array(
CREATE_USER,
DELETE_USER,
EDIT_USER,
...
);
$rights = DELETE_USER + EDIT_USER; // 6
$user_permissions = get_permissions($rights, $permissions);
// [2, 4]
这个单一的 & 符号二进制比较是这样工作的:
1 in binary: 001
2 in binary: 010
4 in binary: 100
7 in binary: 111
7 & 1:
111
001
^ both are not 1, so 0
^ both are not 1, so 0
^ both ARE 1, so 1
---
001 -> is equal to 1, so 7 & 1 == 1 and user has "create_user" permissions
这就是为什么你可以检查 7 & 1 == 1
,因为如果 $permission
是 6(只有 "delete_user" 和 "edit_user" 权限),你会得到这个结果:
6 in binary: 110
6 & 1:
110
001
^ both are not 1, so 0
^ both are not 1, so 0
^ both are not 1, so 0
---
000 -> is NOT equal to 1, so no "create_user" permissions
所以我有一个登录系统,我使用整数列存储用户权限,该列将填充相应的权限编号。我这样做是为了轻松存储多个权限,并保存数据库查询。
所以,这些是我的权限:
create_user = 1
delete_user = 2
edit_user = 4
拥有所有这些权限的用户将拥有权限整数值 7 (1+2+4)。但是,我需要以人类可读的方式呈现用户的权限。
所以我需要做的是再次将 7 解构为这三个数字,最好是用逗号分隔的字符串 (1,2,4
) 但我不能来想出一个函数来做到这一点。
更新:我想这样做是因为我将获取这些整数并根据它们的值转换它们,这样最终用户就可以清楚地看到权限是什么。因此,1,2,4
将变为 Create User,Delete User, Edit User
。
你们有什么智慧吗?
像 @splash58 建议的那样,使用单个 & 符号进行二进制比较。
$permission = 7;
if ($permission & 1 == 1) {
// user has "create_user" permissions
}
if ($permission & 2 == 2) {
// user has "delete_user" permissions
}
if ($permission & 4 == 4) {
// user has "edit_user" permissions
}
大多数使用这种技术进行权限管理的系统都会尝试至少定义人类可读的常量,以防万一您需要更改整数:
define('CREATE_USER', 1);
define('DELETE_USER', 2);
define('EDIT_USER', 4);
$permission = 7;
if ($permission & CREATE_USER == CREATE_USER) {
// user has "create_user" permissions
}
我过去使用过类似类型的授权系统,并且我总是创建一个函数,我可以调用它来检查用户是否具有特定权限,无论我需要放置一些受限的地方 link或检查他们是否被允许查看特定页面:
/**
* Checks whether a user's rights contains a particular permission
*
* @var int $rights sum of a user's rights
* @var int $permission permission to check for
* @return bool
*/
function has_permission($rights, $permission) {
return ($rights & $permission == $permission);
}
通过使用常量,您可以以非常易读的方式调用它:
$permission = 7;
if (has_permission($permission, CREATE_USER)) {
// show the button to create a new user
}
如果您确实需要完全解构用户的权限(例如,您需要获取用户拥有的所有权限的数组),我会将所有可用权限转储到一个数组中并创建一个循环遍历它们的函数:
/**
* Returns an array of all permissions a user has
*
* @var int $rights sum of a user's rights
* @var int[] $permissions list of all known permissions
* @return int[]
*/
function get_permissions($rights, $permissions) {
$user_permissions = array();
foreach ($permissions as $permission) {
if ($rights & $permission == $permission) {
$user_permissions[] = $permission;
}
}
return $user_permissions;
}
$permissions = array(
CREATE_USER,
DELETE_USER,
EDIT_USER,
...
);
$rights = DELETE_USER + EDIT_USER; // 6
$user_permissions = get_permissions($rights, $permissions);
// [2, 4]
这个单一的 & 符号二进制比较是这样工作的:
1 in binary: 001
2 in binary: 010
4 in binary: 100
7 in binary: 111
7 & 1:
111
001
^ both are not 1, so 0
^ both are not 1, so 0
^ both ARE 1, so 1
---
001 -> is equal to 1, so 7 & 1 == 1 and user has "create_user" permissions
这就是为什么你可以检查 7 & 1 == 1
,因为如果 $permission
是 6(只有 "delete_user" 和 "edit_user" 权限),你会得到这个结果:
6 in binary: 110
6 & 1:
110
001
^ both are not 1, so 0
^ both are not 1, so 0
^ both are not 1, so 0
---
000 -> is NOT equal to 1, so no "create_user" permissions