DbManager是生产环境唯一靠谱的选择,PhpManager仅适合本地验证;需确保数据库连接正常、四张权限表存在、MySQL 8+使用utf8mb4字符集;userId和getId()必须返回int;每次修改后调用invalidateCache();权限名仅支持字母、数字、下划线、连字符;角色继承需显式addChild()且status=1才生效。

DbManager 是生产环境唯一靠谱的选择,PhpManager 只适合本地快速验证,一上真环境就掉链子。
DbManager 表没建出来,迁移命令直接报错
执行 yii migrate --migrationPath=@yii/rbac/migrations 报错,不是脚本有问题,而是数据库连接压根没通或 migration 表缺失。必须先确认:
-
config/main.php或config/web.php里db组件已正确定义,dsn、username、password全部可连 - 手动查库,看是否存在
auth_item、auth_item_child、auth_assignment、auth_rule四张表;没有就别硬跑迁移 - MySQL 8+ 用户注意:
Specified key was too long错误大概率是字符集惹的祸,建库时先执行:ALTER DATABASE `your_db_name` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci
角色加进去了,但 Yii::$app->user->can() 一直返回 false
不是代码写错了,是缓存和类型两个坑卡住了。常见表现:调了 $auth->addRole() 和 $auth->assign(),数据库里数据也写了,但权限判断始终不生效。
-
$userId必须是整数(int),传字符串如'123'会导致auth_assignment.user_id写入为0 -
User::identityClass模型里的getId()方法必须返回int,不能是string或NULL - 每次增删角色、分配/撤回权限后,必须立刻调用
Yii::$app->authManager->invalidateCache(),否则can()读的是旧缓存 - 如果用了 Redis/APCu 做缓存,确认
authManager配置里'cache' => 'cache'指向的是那个组件;设成null可临时关缓存排查
权限名或角色名含非法字符,静默失败
Yii2 对 name 字段校验极严,不符合规范不会报错,而是直接跳过写入 —— 这是最容易被忽略的“无感失败”。
- 权限名(
$permission->name)和角色名($role->name)只允许字母、数字、下划线_、连字符- -
post.create、admin:edit、用户管理这类含点、冒号、中文或空格的写法,$auth->add()会返回false且不抛异常 - 建议统一用小写字母 + 下划线,比如
create_post、manage_user
角色继承没生效,addChild() 被当成摆设
RABC 不自动推导父子关系,所有继承链都得显式声明,漏一步,权限就断在半路。
- 创建角色后默认
status = 0(禁用),必须手动设为1才能参与权限计算 -
$auth->addChild($admin, $editor)这句必须执行,仅靠$auth->assign($admin, $userId)不会让用户获得$editor的权限 - 如果角色要继承权限,也要用
addChild()挂到具体Permission上,比如$auth->addChild($editor, $create_post) - 直接改
auth_item_child表绕过 API?风险极高 —— AuthManager 缓存键和内部状态会立刻脱节,线上问题难定位
真正麻烦的从来不是“怎么加权限”,而是“为什么加了没用”。缓存、ID 类型、name 格式、status 状态、addChild 显式调用——这五处任何一个出问题,都会让权限逻辑看起来像随机失效。上线前务必逐条核对,别信“应该没问题”。











