ThinkPHP 5.1.5中执行SQL文件本身不修改角色,需在SQL中操作role_user中间表实现角色增删改;执行后必须清除权限缓存并更新session,否则权限不生效。

ThinkPHP 5.1.5 中“执行 SQL 文件”本身不直接修改角色,它只是批量执行 SQL 语句;真正修改用户角色,需在 SQL 文件中写明对用户表或中间表(如 role_user)的 INSERT、UPDATE 或 DELETE 操作。关键不在“怎么执行”,而在于“SQL 文件里写什么”以及“执行后权限是否实时生效”。
SQL 文件中正确修改角色的写法
角色分配本质是维护用户与角色的多对多关系,必须操作中间表 role_user(非用户表本身)。示例:
- 给用户 ID=123 分配角色 ID=5:
INSERT INTO role_user (user_id, role_id) VALUES (123, 5); - 移除用户 ID=123 的所有角色:
DELETE FROM role_user WHERE user_id = 123; - 将其角色全部替换为 [2, 7]:
DELETE FROM role_user WHERE user_id = 123;<br>INSERT INTO role_user (user_id, role_id) VALUES (123, 2), (123, 7);
⚠️ 注意:字段名必须与你数据库中一致(如 user_id / uid、role_id / rid),ThinkPHP 不做自动映射,写错即报错。
执行 SQL 后权限没变?这是正常现象
执行完 SQL 只改了数据库,但当前登录用户的会话(session)和权限缓存仍是旧的。常见表现:页面刷新后仍显示旧菜单、接口返回 403。必须同步处理运行时状态:
立即学习“PHP免费学习笔记(深入)”;
- 清空该用户的权限缓存(如使用 Redis):
Cache::delete('permission_list_123'); - 强制更新 session 中的用户角色上下文:
$user = User::with('roles.permissions')->find(123);<br>session('user', $user->toArray()); - 若用自定义 Auth 类,需重新初始化或调用
setUser($user)方法
避免手动执行 SQL 的替代方案
长期来看,直接执行 SQL 文件易出错、难审计、无法触发事件。推荐在控制器中封装安全操作:
- 提供「角色分配」接口,校验管理员权限后再调用:
$user->roles()->sync([5, 8]); // ThinkPHP 原生 sync 方法 - 操作完成后主动清除缓存 + 刷新 session,逻辑集中、可记录日志、支持回滚
- SQL 文件仅用于初始化数据(如部署时预置 admin 角色),不用于日常角色调整
不复杂但容易忽略:SQL 改的是库,系统读的是缓存+会话。改完库,务必动缓存和 session,否则等于没改。



















