php 实现rbac
PHP 实现 RBAC(基于角色的访问控制)
RBAC(Role-Based Access Control)是一种常见的权限管理模型,通过角色分配权限,用户通过角色间接获得权限。以下是 PHP 实现 RBAC 的核心步骤和代码示例。
数据库设计
创建以下表结构存储 RBAC 数据:
-
用户表(users)
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE, password VARCHAR(255), role_id INT ); -
角色表(roles)
CREATE TABLE roles ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) UNIQUE ); -
权限表(permissions)
CREATE TABLE permissions ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) UNIQUE, description TEXT ); -
角色-权限关联表(role_permission)
CREATE TABLE role_permission ( role_id INT, permission_id INT, PRIMARY KEY (role_id, permission_id) );
核心功能实现
1. 检查用户权限
通过用户角色关联的权限判断是否允许访问:
function hasPermission($userId, $permissionName) {
// 获取用户角色
$query = "SELECT role_id FROM users WHERE id = ?";
$roleId = executeQuery($query, [$userId])->fetchColumn();
// 获取角色权限
$query = "SELECT p.name FROM permissions p
JOIN role_permission rp ON p.id = rp.permission_id
WHERE rp.role_id = ? AND p.name = ?";
$result = executeQuery($query, [$roleId, $permissionName]);
return $result->rowCount() > 0;
}
2. 权限中间件
在路由或控制器中拦截未授权请求:
function checkPermission($permission) {
if (!hasPermission($_SESSION['user_id'], $permission)) {
header("HTTP/1.1 403 Forbidden");
exit("无权访问");
}
}
// 使用示例
checkPermission("edit_post");
动态菜单生成
根据用户权限渲染可见菜单项:
function getMenuItems($userId) {
$query = "SELECT p.name FROM permissions p
JOIN role_permission rp ON p.id = rp.permission_id
JOIN users u ON u.role_id = rp.role_id
WHERE u.id = ? AND p.name LIKE 'menu_%'";
$permissions = executeQuery($query, [$userId])->fetchAll();
$menu = [];
foreach ($permissions as $p) {
$menu[] = str_replace("menu_", "", $p['name']);
}
return $menu;
}
扩展建议
-
缓存优化
频繁查询数据库会影响性能,建议缓存用户权限数据到 Redis 或 Session 中。 -
超级管理员角色
添加is_superadmin字段到用户表,跳过权限检查。 -
权限分组
在权限表中增加group字段,便于管理同类权限。
完整实现需结合具体框架(如 Laravel 或 Symfony)调整数据库操作方式,但核心逻辑保持一致。







