yii2分组验证需设场景、调validate()而非save()、用json::encode($model->errors)输出json错误;模型中用on指定规则场景,控制器中setscenario()并load后validate,错误结构为字段名映射错误数组。

Yii2 中实现表单的分组验证(scenario)并统一输出 JSON 错误,关键在于:正确设置模型场景、在控制器中调用 validate() 而非 save()、手动捕获并格式化错误。默认情况下,$model->errors 已按属性分组,只需转为 JSON 即可。
确保模型定义了正确的 scenario 和规则
在 Model 类中,需显式声明 scenario,并在 rules() 中使用 on 指定适用场景:
- 在
scenarios()方法中启用场景(如'login'),或直接在rules()中用on参数限定 - 例如登录场景只需验证
username和password,其他字段规则不生效 - 避免遗漏
required规则 —— 分组验证失败通常是因为必填字段为空且未通过校验
控制器中手动触发验证并返回 JSON
不要依赖 save()(它会尝试插入/更新,且默认只对 default 场景生效),改用:
$model->setScenario('login');$model->load(Yii::$app->request->post(), '') && $model->validate();- 验证失败时,用
Json::encode($model->errors)输出(需use yii\helpers\Json;) - 注意:若 POST 数据键名带模型名前缀(如
LoginForm[username]),load()第二个参数保持默认''即可;否则传空字符串防止自动加前缀
前端接收时注意 errors 的结构
Yii2 默认返回的 JSON 是关联数组,格式为:
{"username":["用户名不能为空。"],"password":["密码不能为空。"]}- 每个字段对应一个字符串数组,即使只有一个错误
- 前端 JS 可直接遍历
Object.keys(data)渲染提示,无需额外扁平化 - 如需合并所有错误为单条消息,可用
array_merge(...array_values($model->errors))再 JSON 编码
调试技巧:快速定位验证未生效原因
常见问题包括:
- 场景名拼写错误(大小写敏感),导致规则未加载
-
load()返回 false:检查 POST 数据结构、CSRF 是否开启、字段名是否匹配 - 规则中写了
on但没在scenarios()中声明该场景(Yii2.0.12+ 之后部分版本会静默忽略) - 在控制器中忘了调用
setScenario(),导致始终走default场景











