我正在开发个人 CMS,但遇到了问题。我想将 CAN_DELETE_THREAD、CAN_EDIT_MESSAGE 或 CAN_CREATE_THREAD 等访问级别定义为二进制标志,但我不知道函数“has_flag”如何工作。例如,如果我从数据库中获取一个用户并想检查他是否可以编辑消息,我将如何去做呢?
谢谢!
您需要按用户或按角色访问设置吗?
每个角色将更具可扩展性,特别是如果您的系统将对许多用户开放。
首先,我会定义用户可以执行的操作,按某个类别分组(“线程”与 [添加、编辑、删除、标记、存档、随便]),然后您可以创建一个列表来定义每个角色和每个动作是否被允许或拒绝。
如果您定义一个默认值,您可以减少该表中所需规范的数量(如果没有拒绝,则允许一切,反之亦然)。
需要更多细节以获得进一步的帮助;)
您可以创建一个permissions
数据库表和一个permissions_users
将权限连接到用户的表,然后逐页检查登录用户是否可以查看该页面。
假设您有一个User
模型和一个 ID 为 1 的权限:
if ($user->hasPermission(1)) {
// show form or whatever
}
else {
throw new ForbiddenException();
}
你的hasPermission()
方法可以很简单:
<?php
class User extends Model {
public function hasPermission($permission_id) {
$sql = "SELECT COUNT(*) FROM `permissions_users` WHERE `user_id` = :user_id AND `permission_id` = :permission_id";
$stmt = $this->pdo->prepare($sql);
$stmt->bindParam(':user_id', $this->id, PDO::PARAM_INT);
$stmt->bindParam(':permission_id', $permission_id, PDO::PARAM_INT);
return ($this->pdo->fetchColumn() > 0); // returns true if at least 1 result
}
}
显然,您需要调整它以适合您的应用程序。
您可以通过多种方式做到这一点。您可以存储与用户关联的整数属性,然后将标志定义为 2 的整数幂:
define('CAN_CREATE_THREAD', 0x0010);
define('CAN_DELETE_THREAD', 0x0020);
那么对你hasFlag($flag)
来说可能是这样的
return ($this->BinaryFlags & $flag);
否则,您可以将所有标志存储在数据库中:
CREATE TABLE flags
(
id integer not null primary key auto_increment,
name varchar(32)
);
CREATE TABLE has_flag
(
user_id integer,
flag_id integer
);
并且您的 hasFlag 函数是对数据库的查询。
角色级别的访问权限是相同的,只是您不存储将标志与用户相关联,而是将用户与角色相关联(因此您有一个类似的表(user_id, role_id)
),然后将标志与角色相关联,如上所示。
好处是可以将一个人定义为“部分XYZ管理员”,而不必一一记住和设置所有权限;缺点是您不能拥有中间状态(例如,可以编辑但不能创建的半管理员),除非您先创建角色。