我已经开始在我的 MVC 框架上用 PHP 开发一个论坛应用程序,并且我已经到了为成员分配权限的阶段(例如:READ、WRITE、UPDATE、DELETE)。
现在,我知道我可以在数据库的用户表下添加 5 列并将它们设置为 1 | 0,但是如果我想添加其他规则,例如 MOVE,这对我来说似乎太多了。
以及如何将这些权限分别动态分配给用户?
我听说过使用位掩码,但如果我能在继续之前完全理解它们,那就太好了。
你有我如何实现这个的例子吗?
我已经开始在我的 MVC 框架上用 PHP 开发一个论坛应用程序,并且我已经到了为成员分配权限的阶段(例如:READ、WRITE、UPDATE、DELETE)。
现在,我知道我可以在数据库的用户表下添加 5 列并将它们设置为 1 | 0,但是如果我想添加其他规则,例如 MOVE,这对我来说似乎太多了。
以及如何将这些权限分别动态分配给用户?
我听说过使用位掩码,但如果我能在继续之前完全理解它们,那就太好了。
你有我如何实现这个的例子吗?
权限位掩码最好用二进制表示,每个数字代表打开或关闭的权限。因此,如果权限 X、Y 和 Z 存在,并且我只能访问 X 和 Z,101
则表示我拥有授予我的第一个和第三个权限,但没有第二个权限。二进制数101
等同于十进制数5
,因此最终将存储在数据库中。与字符串或几个小整数相比,单个小整数的存储效率要高得多。
编辑:我意识到利用现有的转换功能来快速实现是多么容易。这是一个示例。
<?php
function bitmask_expand($n) {
// 9 returns array(1, 0, 0, 1)
return str_split(base_convert($n, 10, 2));
}
function bitmask_compact($a) {
// array(1, 0, 0, 1) returns 9
return (int) base_convert(implode($a), 2, 10);
}
$ns = range(0, 7);
foreach($ns as $n) {
print_r($b = bitmask_expand($n));
echo bitmask_compact($b), "\n\n";
}
如果你使用循环,而不是从字符串中拉回和拉出,你可能会获得更好的性能,但这很清楚地说明了这个原理。
您描述的方法(存储在列中的个人权限)很简单,但牺牲了灵活性(正如您所注意到的)。
Zuul 的方法更简单,基本上和你的一样,只是它避免了任何“ALTER TABLE”语句的需要。然而,它没有被规范化,不容易查询,也不是自记录的。
这两种方法的另一个问题是,随着用户群的增长,您会发现正确设置每个人的权限变得越来越痛苦。您会发现自己拥有许多需要完全相同权限的用户。然而,为了更改用户的权限,例如适应新的权限,您必须进入并将该权限添加到每个单独需要它的用户。皮塔少校。
对于论坛,您不太可能需要按用户进行权限管理。您更有可能拥有某些类别的用户,例如匿名用户、登录用户、版主、管理员等。这将使其非常适合基于角色的访问控制 (RBAC)。在此系统中,您将为每个用户分配一个角色,并为该角色授予权限。特权将作为行存储在“特权”表中。所以简化的数据库模式看起来像:
PRIVILEGE
int id (primary key)
varchar description
ROLE_PRIVILEGE_JOIN
privilege_id (foreign key)
role_id (foreign key)
ROLE
int id (primary key)
varchar description
USER
int id (primary key)
int role_id (foreign key)
这种模式用于许多处理用户权限的应用程序中。在权限表中添加任何人可能拥有的每个权限作为一行;在角色表中添加任何用户可能拥有的每个角色;并在 role_privilege_join 表中适当地链接它们。
唯一真正的缺点是因为使用了连接表,“用户 X 是否可以做 Y”查询会有点慢。
我会创建一个名为“角色”的表:
CREATE TABLE Roles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
rolename VARCHAR(30))
在其中粘贴您想要的任何权限。然后创建一个名为“UserRoles”的表来将用户链接到角色:
CREATE TABLE UserRoles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
UserId INT,
RoleID INT)
非常灵活且易于构建(即工作流、规则等)(我也会添加外键)
您不需要复杂化,只需使用字段“ex:permissions”并执行以下操作:
$permissions = "1;1;0;1";
你关心的地方是:
阅读 - 1(罐头)
写 - 1(可以)
更新 - 0(不能)
删除 - 1(可以)
然后,在检查时,只需通过“;”使用“explode”......
这样,您始终可以在不更改表的情况下应用更多权限类型......因此您的表更小,查询更快!
这是您的问题的解决方法:)