Yii2中控制器应返回数组而非手动echo JSON,验证失败时用return ['success'=>false,'errors'=>$model->getErrors()],并确保response格式为JSON、禁用CSRF验证。

在 Yii2 中,控制器捕获表单验证失败后输出 JSON 响应,关键不是“手动 echo json_encode()”,而是让验证流程自然走到 Yii 的响应机制里,并确保错误信息以标准 JSON 格式返回。重点在于模型验证、控制器动作写法、以及响应格式的统一控制。
确保模型验证正确触发并收集错误
验证必须在 save() 或 validate() 调用后显式检查,不能只依赖自动行为:
- 调用
$model->load($request->post())后,必须紧接着调用$model->validate()或$model->save()(后者内部会先 validate) - 验证失败时,
$model->hasErrors()返回 true,错误信息存在$model->getErrors()中 - 避免用
echo var_dump(...)调试;推荐用:if (!$model->validate()) { return ['success' => false, 'errors' => $model->getErrors()]; }
控制器动作中直接 return 数组,不 exit / die / echo
Yii2 的 REST 控制器(如 yii\rest\Controller)或配置了 JSON 格式的普通控制器,会自动将数组转为 JSON 响应。务必避免中断流程:
- ✅ 正确:
return ['code' => 400, 'message' => '验证失败', 'errors' => $model->getErrors()]; - ❌ 错误:
var_dump($model->getErrors()); exit;或echo json_encode([...]); - 若继承
yii\web\Controller,需提前确保Yii::$app->response->format = Response::FORMAT_JSON;已设置(建议在 beforeAction 或行为中统一处理)
统一错误结构:把验证错误包进标准格式
不要让前端收到原始 getErrors() 的嵌套结构(如 ['username' => ['用户名不能为空']]),可做一层转换:
- 提取所有字段错误合并为扁平提示:
array_values($model->getFirstErrors())得到首个错误列表 - 或构造业务友好结构:
['code' => 1001, 'message' => '参数校验不通过', 'details' => $model->getErrors()] - 注意:如果使用
ActiveController,它默认返回['name' => 'Validation Failed', 'message' => '...'],可重写afterAction()或在actions()中自定义 error handler
避免 CSRF 验证干扰 API 表单提交
纯 API 接口(如移动端、小程序)通常不带 Yii CSRF token,需关闭验证,否则 load() 会静默失败:
- 在控制器中禁用:
public $enableCsrfValidation = false; - 或更精细地:用 Behavior 按 action 关闭(见知识库中
NoCsrf示例) - 确认请求头
Content-Type: application/json已正确设置,否则load()可能无法识别数据来源











