Yii2批量删除需与RBAC协同设计,权限检查必须前置且不可绕过;应定义业务粒度专属权限项(如adjustment/batch-delete),在AccessControl中显式绑定;deleteAll前须补充租户隔离、关键数据排除等业务校验;操作日志需在事务内记录以保障审计完整性。

Yii2 中批量删除操作与 RBAC 权限控制必须协同设计,否则容易出现「能删但不该删」或「该删却无权删」的问题。核心原则是:RBAC 控制入口权限,deleteAll() 执行时不做二次校验,所以权限检查必须前置、明确、不可绕过。
定义专属删除权限项
不要复用通用权限名(如 delete),应按业务场景粒度定义清晰的权限项,例如:
- adjustment/batch-delete:用于调整项批量删除
- user/inactive-batch-delete:仅允许对非活跃用户批量清理
- log/clear-old:日志表按时间范围批量清除
在 RBAC 初始化代码中注册:
$auth = Yii::$app->authManager;
$perm = $auth->createPermission('adjustment/batch-delete');
$perm->description = '允许批量删除调整配置';
$auth->add($perm);
在控制器中做权限拦截
批量删除接口(如 actionBatchDelete)必须显式声明权限要求,推荐使用 AccessControl 行为:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['batch-delete'],
'allow' => true,
'roles' => ['@'],
'permissions' => ['adjustment/batch-delete'], // ✅ 关键:绑定具体权限项
],
],
],
];
}
注意:不能只靠角色(如 'admin')放行,因为 RBAC 的优势在于细粒度控制——同一角色下不同用户可能被赋予不同批量删除权限。
执行 deleteAll 前再做一次业务级校验
RBAC 只管“能不能删”,不管“删哪些才安全”。因此在调用 deleteAll() 前,需结合当前用户上下文补充限制条件:
- 限制可操作的数据范围(如仅本部门数据、仅本人创建的记录)
- 排除系统关键记录(如
['NOT', ['id' => [1, 2]]]) - 校验参数合法性(如
$plan_year_id是否属于用户可见年度)
示例:
// 获取用户所属部门 ID
$deptId = Yii::$app->user->identity->department_id;
// 构建带租户隔离的条件
$condition = [
'AND',
['plan_year_id' => $plan_year_id],
['dept_id' => $deptId], // ✅ 加入业务维度约束
['is_auto' => $is_auto],
['NOT', ['column_id' => 1]],
];
AllAdjustments::deleteAll($condition);
记录操作日志并触发审计
批量删除影响大,建议在事务中同步写入操作日志:
- 记录操作人、时间、IP、影响行数、实际 SQL 条件(脱敏后)
- 若涉及敏感数据,可对接规则(Rule)做动态审批,例如「删除超 100 条需主管二次确认」
- 避免在 deleteAll 后才记录日志——失败时日志缺失,应放在事务内统一提交
RBAC 本身不提供日志功能,需自行扩展或集成 yii\log\Target 或数据库日志表。


















