本文目录导读:

我来详细介绍PHP项目中RBAC权限模型的搭建方案。
数据库设计
基础表结构
-- 用户表
CREATE TABLE `users` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`email` VARCHAR(100),
`status` TINYINT DEFAULT 1,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 角色表
CREATE TABLE `roles` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`description` VARCHAR(200),
`status` TINYINT DEFAULT 1,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 用户角色关联表
CREATE TABLE `user_roles` (
`user_id` INT NOT NULL,
`role_id` INT NOT NULL,
PRIMARY KEY (`user_id`, `role_id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`),
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`)
);
-- 权限表
CREATE TABLE `permissions` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`code` VARCHAR(100) NOT NULL UNIQUE, -- 权限代码
`module` VARCHAR(50), -- 所属模块
`description` VARCHAR(200),
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 角色权限关联表
CREATE TABLE `role_permissions` (
`role_id` INT NOT NULL,
`permission_id` INT NOT NULL,
PRIMARY KEY (`role_id`, `permission_id`),
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`),
FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`)
);
RBAC核心类实现
PermissionManager.php
<?php
class PermissionManager {
private $db;
public function __construct($db) {
$this->db = $db;
}
/**
* 获取用户所有权限
*/
public function getUserPermissions($userId) {
$sql = "SELECT DISTINCT p.code, p.name, p.module
FROM permissions p
JOIN role_permissions rp ON p.id = rp.permission_id
JOIN user_roles ur ON rp.role_id = ur.role_id
WHERE ur.user_id = :user_id";
$stmt = $this->db->prepare($sql);
$stmt->execute(['user_id' => $userId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 检查用户是否有指定权限
*/
public function checkPermission($userId, $permissionCode) {
$sql = "SELECT COUNT(*) as count
FROM user_roles ur
JOIN role_permissions rp ON ur.role_id = rp.role_id
JOIN permissions p ON rp.permission_id = p.id
WHERE ur.user_id = :user_id
AND p.code = :permission_code";
$stmt = $this->db->prepare($sql);
$stmt->execute([
'user_id' => $userId,
'permission_code' => $permissionCode
]);
return $stmt->fetch(PDO::FETCH_ASSOC)['count'] > 0;
}
/**
* 检查用户是否有多个权限(且关系)
*/
public function checkAllPermissions($userId, array $permissionCodes) {
$placeholders = implode(',', array_fill(0, count($permissionCodes), '?'));
$sql = "SELECT DISTINCT p.code
FROM user_roles ur
JOIN role_permissions rp ON ur.role_id = rp.role_id
JOIN permissions p ON rp.permission_id = p.id
WHERE ur.user_id = ?
AND p.code IN ($placeholders)";
$stmt = $this->db->prepare($sql);
$params = array_merge([$userId], $permissionCodes);
$stmt->execute($params);
$userPermissions = $stmt->fetchAll(PDO::FETCH_COLUMN);
return count(array_intersect($permissionCodes, $userPermissions)) == count($permissionCodes);
}
}
RoleManager.php
<?php
class RoleManager {
private $db;
public function __construct($db) {
$this->db = $db;
}
/**
* 为用户分配角色
*/
public function assignRole($userId, $roleId) {
$sql = "INSERT IGNORE INTO user_roles (user_id, role_id)
VALUES (:user_id, :role_id)";
$stmt = $this->db->prepare($sql);
return $stmt->execute([
'user_id' => $userId,
'role_id' => $roleId
]);
}
/**
* 移除用户角色
*/
public function removeRole($userId, $roleId) {
$sql = "DELETE FROM user_roles
WHERE user_id = :user_id AND role_id = :role_id";
$stmt = $this->db->prepare($sql);
return $stmt->execute([
'user_id' => $userId,
'role_id' => $roleId
]);
}
/**
* 获取用户所有角色
*/
public function getUserRoles($userId) {
$sql = "SELECT r.* FROM roles r
JOIN user_roles ur ON r.id = ur.role_id
WHERE ur.user_id = :user_id";
$stmt = $this->db->prepare($sql);
$stmt->execute(['user_id' => $userId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 为角色分配权限
*/
public function assignPermission($roleId, $permissionId) {
$sql = "INSERT IGNORE INTO role_permissions (role_id, permission_id)
VALUES (:role_id, :permission_id)";
$stmt = $this->db->prepare($sql);
return $stmt->execute([
'role_id' => $roleId,
'permission_id' => $permissionId
]);
}
}
中间件实现
AuthMiddleware.php
<?php
class AuthMiddleware {
private $permissionManager;
private $session;
public function __construct($permissionManager, $session) {
$this->permissionManager = $permissionManager;
$this->session = $session;
}
/**
* 检查是否登录
*/
public function requireLogin() {
if (!$this->session->has('user_id')) {
header('Location: /login');
exit;
}
}
/**
* 检查权限
*/
public function requirePermission($permissionCode) {
$this->requireLogin();
$userId = $this->session->get('user_id');
if (!$this->permissionManager->checkPermission($userId, $permissionCode)) {
// 返回403禁止访问
http_response_code(403);
echo json_encode(['error' => 'Access denied']);
exit;
}
}
}
使用示例
权限检查与路由
<?php
// 初始化
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$permissionManager = new PermissionManager($db);
$authMiddleware = new AuthMiddleware($permissionManager, $_SESSION);
// 路由示例
class UserController {
// 需要登录才能访问
public function profile() {
global $authMiddleware;
$authMiddleware->requireLogin();
// 显示用户信息
}
// 需要特定权限
public function deleteUser($userId) {
global $authMiddleware;
$authMiddleware->requirePermission('user.delete');
// 执行删除操作
}
// 需要多个权限
public function adminPanel() {
global $authMiddleware;
$authMiddleware->requirePermission('admin.access');
// 管理员面板
}
}
// 缓存用户权限
class UserPermissionCache {
private $cache = [];
public function getUserPermissions($userId) {
if (!isset($this->cache[$userId])) {
$this->cache[$userId] = $this->loadPermissions($userId);
}
return $this->cache[$userId];
}
}
进阶优化
缓存优化
<?php
class PermissionCache {
private $redis;
private $ttl = 3600; // 1小时缓存
public function getCachedPermissions($userId) {
$key = "user_permissions:{$userId}";
$cached = $this->redis->get($key);
if ($cached) {
return json_decode($cached, true);
}
$permissions = $this->loadFromDatabase($userId);
$this->redis->setex($key, $this->ttl, json_encode($permissions));
return $permissions;
}
public function clearUserCache($userId) {
$this->redis->del("user_permissions:{$userId}");
}
}
树形权限结构
<?php
class TreePermissionManager extends PermissionManager {
public function getPermissionTree() {
$sql = "SELECT id, name, code, parent_id
FROM permissions
ORDER BY parent_id, sort_order";
$permissions = $this->db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
return $this->buildTree($permissions);
}
private function buildTree(array $items, $parentId = null) {
$tree = [];
foreach ($items as $item) {
if ($item['parent_id'] === $parentId) {
$children = $this->buildTree($items, $item['id']);
if ($children) {
$item['children'] = $children;
}
$tree[] = $item;
}
}
return $tree;
}
}
这个RBAC权限模型提供了完整的权限管理解决方案,包括数据库设计、核心类实现、中间件集成和缓存优化等关键功能,你可以根据具体项目需求进行调整和扩展。