我已经开始在MVC框架上开发PHP中的论坛应用程序,并且已经进入了将权限分配给会员的阶段(例如:阅读,写作,更新,删除)。

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

我如何将这些特权动态分配给用户单独分配?

我听说过使用了一个bitmasks,但是如果我能在继续之前能够完全理解它们,那真的很好。

您有一个例子说明我如何实施此功能吗?

有帮助吗?

解决方案

您描述的方法 - 存储在列中的单个特权 - 以灵活性为代价(您注意到)。

Zuul的方法更简单,本质上与您的方法相同,除非它避免了对任何“ Alter Table”语句的需要。但是,它不归一化,不容易查询,也不是自我证明的。

这两种方法的另一个问题是,随着用户群的增长,您会发现越来越多的痛苦使每个人的特权设定正确。您会发现自己与许多需要完全相同特权的用户。然而,为了更改用户的特权,例如适应新的特权,您将不得不进入并向每个需要单独使用的用户添加该特权。 PITA少校。

对于论坛,您不太可能需要每用户特权管理。您更有可能拥有某些类别的用户,例如匿名用户,登录用户,主持人,管理员等。这将非常适合基于角色的访问控制(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)

此模式用于许多涉及用户特权的应用程序。添加任何人都可以作为特权表中的一行的所有特权;添加任何用户在角色表中可能扮演的每个角色;并在COOL_PRIVILEGE_JOIN表中适当链接它们。

唯一真正的缺点是,由于使用了一个联接表,因此“ Can user x do y”查询将会慢一点。

其他提示

当表示为二进制时,最好理解一个权限bitmask,每个数字代表已打开或关闭的许可。因此,如果存在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";
}

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

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

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 =“ 1; 1; 0; 1”;

在您的关注下,它在哪里阅读:

阅读-1(can)

写入-1(can)

更新-0(不能)

删除-1(can)

然后,在检查时,只需使用“爆炸”;“ ...

这样,您始终可以在不更改表的情况下应用更多的权限类型……因此,您的桌子较小,并且查询速度更快!

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top