4

我已经开始在我的 MVC 框架上用 PHP 开发一个论坛应用程序,并且我已经到了为成员分配权限的阶段(例如:READ、WRITE、UPDATE、DELETE)。

现在,我知道我可以在数据库的用户表下添加 5 列并将它们设置为 1 | 0,但是如果我想添加其他规则,例如 MOVE,这对我来说似乎太多了。

以及如何将这些权限分别动态分配给用户?

我听说过使用位掩码,但如果我能在继续之前完全理解它们,那就太好了。

你有我如何实现这个的例子吗?

4

4 回答 4

4

权限位掩码最好用二进制表示,每个数字代表打开或关闭的权限。因此,如果权限 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";
}

如果你使用循环,而不是从字符串中拉回和拉出,你可能会获得更好的性能,但这很清楚地说明了这个原理。

于 2010-05-30T02:37:05.767 回答
3

您描述的方法(存储在列中的个人权限)很简单,但牺牲了灵活性(正如您所注意到的)。

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”查询会有点慢。

于 2010-05-30T02:55:24.853 回答
1

我会创建一个名为“角色”的表:

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)

非常灵活且易于构建(即工作流、规则等)(我也会添加外键)

于 2010-05-30T02:38:25.237 回答
-1

您不需要复杂化,只需使用字段“ex:permissions”并执行以下操作:

$permissions = "1;1;0;1";

你关心的地方是:

阅读 - 1(罐头)

写 - 1(可以)

更新 - 0(不能)

删除 - 1(可以)

然后,在检查时,只需通过“;”使用“explode”......

这样,您始终可以在不更改表的情况下应用更多权限类型......因此您的表更小,查询更快!

这是您的问题的解决方法:)

于 2010-05-30T02:35:40.487 回答