CRUD系统中如何获取用户权限?
权限获取优化方案
针对你的需求,这里提供几个实用的优化方向:
1. 精简Session存储的权限数据
你当前的代码会把权限表的所有字段存入Session,体积冗余且没必要。可以只提取关键权限标识,转成键值对结构存储,大幅压缩存储体积:
// 优化SQL,只查询需要的权限字段,避免SELECT * $permissions = sqlSelect($conn, ' SELECT permissions.key, permissions.value FROM permissions INNER JOIN roles ON permissions.role_id = roles.id INNER JOIN users_role ON permissions.role_id = users_role.role_id WHERE users_role.user_id = ?', 'i', $row['id']); $user_permissions = []; while ($permission_row = $permissions->fetch_assoc()) { // 转成键值对,比如 $user_permissions['can_edit'] = true $user_permissions[$permission_row['key']] = $permission_row['value']; } $_SESSION['logged'] = true; // 存储精简后的权限,体积大幅减小 $_SESSION['user_permissions'] = $user_permissions;
如果权限是布尔型或固定枚举值,还可以用位掩码进一步压缩:把每个权限映射成一个二进制位,最终用一个整数表示所有权限(12个权限仅需一个int字段存储),读取时通过位运算判断权限状态。
2. 使用缓存中间件替代Session
用Redis、Memcached这类缓存工具存储权限数据,相比Session优势明显:
- 存储容量更大、读写性能更高
- 可设置合理过期时间(比如登录后2小时自动过期,过期重新加载)
- 支持分布式部署,适配多服务器场景
示例代码(Redis):
// 连接Redis $redis = new Redis(); $redis->connect('127.0.0.1', 6379); // 生成唯一缓存键 $cacheKey = 'user_perms_' . $row['id']; // 优先从缓存读取 $user_permissions = $redis->get($cacheKey); if (!$user_permissions) { // 缓存不存在时查询数据库 $permissions = sqlSelect($conn, ' SELECT permissions.key, permissions.value FROM permissions INNER JOIN roles ON permissions.role_id = roles.id INNER JOIN users_role ON permissions.role_id = users_role.role_id WHERE users_role.user_id = ?', 'i', $row['id']); $user_permissions = []; while ($permission_row = $permissions->fetch_assoc()) { $user_permissions[$permission_row['key']] = $permission_row['value']; } // 存入缓存,设置2小时过期 $redis->setex($cacheKey, 7200, json_encode($user_permissions)); } else { $user_permissions = json_decode($user_permissions, true); } // 可选:把精简后的权限存入Session,后续直接从Session读取 $_SESSION['user_permissions'] = $user_permissions;
3. 按需加载权限模块
如果权限按业务模块划分(比如用户管理、订单管理),可以只在用户进入对应模块时加载该模块权限,而非一次性全量加载:
// 封装模块权限查询函数 function getModulePermissions($conn, $userId, $module) { $permissions = sqlSelect($conn, ' SELECT permissions.key, permissions.value FROM permissions INNER JOIN roles ON permissions.role_id = roles.id INNER JOIN users_role ON permissions.role_id = users_role.role_id WHERE users_role.user_id = ? AND permissions.module = ?', 'is', [$userId, $module]); $modulePerms = []; while ($permission_row = $permissions->fetch_assoc()) { $modulePerms[$permission_row['key']] = $permission_row['value']; } return $modulePerms; } // 使用示例:用户进入订单管理页面时加载订单权限 $orderPerms = getModulePermissions($conn, $row['id'], 'order'); $_SESSION['order_permissions'] = $orderPerms;
4. 优化数据库查询效率
- 给
users_role.user_id、permissions.role_id、roles.id这些关联字段建立索引,加快关联查询速度 - 严格避免
SELECT *,只查询业务需要的字段,减少数据传输量
内容的提问来源于stack exchange,提问作者novaztar
相关产品推荐
相关产品推荐

