本文目录导读:

我来介绍几种PHP数据权限的实现方案,从简单到复杂,你可以根据项目需求选择合适的方案。
基于角色的数据权限方案
基础RBAC模型
<?php
// 权限配置类
class PermissionConfig {
// 用户角色
const ROLE_ADMIN = 'admin'; // 管理员
const ROLE_MANAGER = 'manager'; // 部门经理
const ROLE_STAFF = 'staff'; // 普通员工
// 数据权限级别
const SCOPE_ALL = 'all'; // 全部数据
const SCOPE_DEPARTMENT = 'dept'; // 本部门数据
const SCOPE_SELF = 'self'; // 本人数据
const SCOPE_CUSTOM = 'custom'; // 自定义范围
// 角色对应的默认数据权限
private static $roleScope = [
self::ROLE_ADMIN => self::SCOPE_ALL,
self::ROLE_MANAGER => self::SCOPE_DEPARTMENT,
self::ROLE_STAFF => self::SCOPE_SELF,
];
public static function getScopeForRole($role) {
return self::$roleScope[$role] ?? self::SCOPE_SELF;
}
}
数据权限过滤类
<?php
class DataPermission {
private $user;
private $db;
public function __construct($user, $db) {
$this->user = $user;
$this->db = $db;
}
/**
* 生成数据权限SQL条件
* @param string $alias 表别名
* @param string $userIdField 用户ID字段
* @param string $deptIdField 部门ID字段
*/
public function getPermissionSQL($alias = '', $userIdField = 'user_id', $deptIdField = 'dept_id') {
$scope = PermissionConfig::getScopeForRole($this->user->role);
$aliasPrefix = $alias ? $alias . '.' : '';
switch ($scope) {
case PermissionConfig::SCOPE_ALL:
return '1=1';
case PermissionConfig::SCOPE_DEPARTMENT:
return "{$aliasPrefix}{$deptIdField} IN (
SELECT dept_id FROM user_depts
WHERE user_id = {$this->user->id}
UNION
SELECT dept_id FROM depts
WHERE parent_id IN (
SELECT dept_id FROM user_depts
WHERE user_id = {$this->user->id}
)
)";
case PermissionConfig::SCOPE_SELF:
return "{$aliasPrefix}{$userIdField} = {$this->user->id}";
case PermissionConfig::SCOPE_CUSTOM:
return $this->getCustomScopeSQL();
default:
return '1=0';
}
}
/**
* 应用数据权限过滤
*/
public function applyPermission($sql) {
$permissionSQL = $this->getPermissionSQL();
// 检查是否已有WHERE条件
if (stripos($sql, ' WHERE ') !== false) {
$sql .= " AND {$permissionSQL}";
} else {
$sql .= " WHERE {$permissionSQL}";
}
return $sql;
}
private function getCustomScopeSQL() {
// 从用户权限表获取自定义的数据范围
$sql = "SELECT data_ids FROM user_data_scopes
WHERE user_id = {$this->user->id}";
$result = $this->db->query($sql);
$ids = $result->fetchColumn();
return $ids ? "id IN ({$ids})" : '1=0';
}
}
使用示例
<?php
// 在查询中使用数据权限
class UserController {
public function getUsers() {
$user = getCurrentUser();
$db = getDB();
$permission = new DataPermission($user, $db);
$sql = "SELECT * FROM users u
WHERE u.status = 1";
// 应用数据权限
$sql = $permission->applyPermission($sql);
$result = $db->query($sql);
return $result->fetchAll();
}
}
基于规则的动态权限方案
规则引擎
<?php
class RuleEngine {
private $rules = [];
private $context;
public function setContext($context) {
$this->context = $context;
}
public function addRule($rule) {
$this->rules[] = $rule;
}
public function execute() {
foreach ($this->rules as $rule) {
if ($rule->evaluate($this->context)) {
return $rule->apply($this->context);
}
}
return false;
}
}
// 规则接口
interface Rule {
public function evaluate($context);
public function apply($context);
}
// 部门范围规则
class DepartmentRule implements Rule {
public function evaluate($context) {
return $context['role'] === 'manager';
}
public function apply($context) {
return "dept_id IN (SELECT dept_id FROM user_depts
WHERE user_id = {$context['user_id']})";
}
}
// 自定义范围规则
class CustomScopeRule implements Rule {
public function evaluate($context) {
return $context['role'] === 'project_leader';
}
public function apply($context) {
return "project_id IN (SELECT project_id FROM project_leaders
WHERE user_id = {$context['user_id']})";
}
}
动态规则配置
<?php
// 数据库表结构
CREATE TABLE data_permission_rules (
id INT PRIMARY KEY AUTO_INCREMENT,
role VARCHAR(50),
rule_type VARCHAR(50),
rule_config TEXT,
priority INT DEFAULT 0,
status TINYINT(1) DEFAULT 1
);
// 规则加载器
class RuleLoader {
public function loadRules($role) {
$sql = "SELECT * FROM data_permission_rules
WHERE role = '{$role}' AND status = 1
ORDER BY priority DESC";
// 返回规则数组
return $this->db->fetchAll($sql);
}
public function buildRule($row) {
switch ($row['rule_type']) {
case 'department':
return new DepartmentRule();
case 'custom':
$rule = new CustomScopeRule();
$rule->setConfig(json_decode($row['rule_config'], true));
return $rule;
// 更多规则类型...
}
}
}
基于AOP注解的方式
<?php
/**
* 数据权限注解
* @Annotation
*/
class DataPermissionAnnotation {
public $subject; // 数据主体
public $scope; // 权限范围
public $field; // 字段
}
// 使用注解的控制器
class OrderController {
/**
* @DataPermissionAnnotation(subject="order", scope="dept", field="dept_id")
*/
public function getOrders() {
// 业务逻辑
return $this->orderService->getList();
}
}
// 注解处理器
class DataPermissionAspect {
public function process($controller, $method) {
$reflection = new ReflectionMethod($controller, $method);
$docComment = $reflection->getDocComment();
if (preg_match('/@DataPermissionAnnotation\((.*?)\)/', $docComment, $matches)) {
$config = $this->parseAnnotation($matches[1]);
return $this->buildPermissionSQL($config);
}
return '1=1';
}
}
通用解决方案封装
权限管理器
<?php
class PermissionManager {
private static $instance;
private $db;
private $user;
private $handlers = [];
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function setUser($user) {
$this->user = $user;
return $this;
}
public function registerHandler($subject, $handler) {
$this->handlers[$subject] = $handler;
return $this;
}
public function buildQuery($subject, $table, $params = []) {
$handler = $this->handlers[$subject] ?? null;
if ($handler) {
return $handler->buildQuery($this->user, $table, $params);
}
// 默认处理
return $this->defaultHandler($table, $params);
}
private function defaultHandler($table, $params) {
// 默认实现
$sql = "SELECT * FROM {$table} WHERE 1=1";
if (isset($params['dept_id'])) {
$sql .= $this->buildDeptCondition($params['dept_id']);
}
return $sql;
}
}
// 使用示例
PermissionManager::getInstance()
->setUser($currentUser)
->registerHandler('order', new OrderPermissionHandler())
->registerHandler('product', new ProductPermissionHandler());
$sql = PermissionManager::getInstance()->buildQuery('order', 'orders', [
'dept_id' => 100,
'status' => 1
]);
缓存优化
<?php
class PermissionCache {
private $cache;
private $ttl = 3600;
public function getPermissionSQL($userId, $subject) {
$key = "permission:{$userId}:{$subject}";
return $this->cache->remember($key, $this->ttl, function() use ($userId, $subject) {
return $this->buildPermissionSQL($userId, $subject);
});
}
public function clearPermission($userId) {
$pattern = "permission:{$userId}:*";
$this->cache->deleteByPattern($pattern);
}
}
最佳实践建议
架构设计
<?php
// 分层设计
class PermissionLayer {
// 1. 认证层
public function authenticate($token) {
// 验证用户身份
}
// 2. 授权层
public function authorize($user, $action, $resource) {
// 验证操作权限
if (!$this->checkPermission($user, $action, $resource)) {
throw new UnauthorizedException('无权限执行此操作');
}
}
// 3. 数据过滤层
public function filter($query, $user) {
// 添加数据过滤条件
return $this->applyDataPermission($query, $user);
}
// 4. 敏感字段脱敏层
public function mask($data, $user) {
// 对敏感字段进行脱敏
return $this->maskSensitiveFields($data, $user);
}
}
性能优化
<?php
class OptimizedPermissionService {
public function getAllowedIds($user, $type) {
$key = "allowed_ids:{$type}:{$user->id}";
// 1. 先查缓存
if ($ids = $this->getFromCache($key)) {
return $ids;
}
// 2. 缓存未命中,查询数据库
$ids = $this->queryAllowedIds($user, $type);
// 3. 放入缓存
$this->setCache($key, $ids);
return $ids;
}
// 批量查询优化
public function filterBatchData($datas, $user) {
$allowedIds = $this->getAllowedIds($user, 'data');
// 使用array_filter进行内存过滤
return array_filter($datas, function($data) use ($allowedIds) {
return in_array($data['id'], $allowedIds);
});
}
}
安全考虑
<?php
class SecurePermission {
// SQL注入防护
public static function sanitizeValue($value) {
return intval($value); // 或使用预编译语句
}
// 越权防护
public static function preventPrivilegeEscalation($user, $requestedAction) {
// 检查是否为高权限操作
if (in_array($requestedAction, ['delete', 'update_all', 'export'])) {
// 二次验证
return $this->doubleVerification($user);
}
return true;
}
// 日志审计
public static function audit($userId, $action, $data, $result) {
$log = [
'user_id' => $userId,
'action' => $action,
'data' => json_encode($data),
'result' => $result ? 'success' : 'denied',
'ip' => $_SERVER['REMOTE_ADDR'],
'time' => date('Y-m-d H:i:s')
];
// 写入审计日志
self::writeAuditLog($log);
}
}
选择数据权限方案时需要综合考虑:
- 项目规模:大型项目建议使用规则引擎,小型项目使用简单的RBAC即可
- 灵活性需求:需要动态调整权限时使用规则配置方案
- 性能要求:高并发场景需要考虑缓存和优化策略
- 安全性:必须防护SQL注入和越权访问
建议从基础RBAC开始,根据业务需求逐步演进出更复杂的权限模型,同时保持良好的扩展性和可维护性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播