PHP中人类可读的逻辑权限

时间:2017-04-15 14:45:59

标签: php permissions logical-operators

所以我有一个登录系统,我使用整数列存储用户权限,该整数列将填充相应的权限编号。我通过这种方式轻松存储多个权限,并保存数据库查询。

所以,这些是我的权限:

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

你们有什么智慧吗?

1 个答案:

答案 0 :(得分:3)

使用单个&符号进行二进制比较,如@ 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
}

我过去曾使用过类似的授权系统,而且我总是会创建一个函数,我可以调用该函数来检查用户是否在我需要放置某些受限制的链接或检查时具有特定权限如果他们被允许查看特定页面:

/**
 * 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(仅#34; 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