Yii2 API场景需统一JSON返回验证结果:拦截validateAction和save失败流程,重写响应格式;标准化错误结构为扁平化数组;全局封装响应逻辑确保Content-Type正确。

Yii2 表单验证默认返回 HTML 页面或重定向,但在前后端分离或 API 场景下,需要统一以 JSON 格式返回验证结果(含错误字段、消息、状态码)。关键在于拦截验证失败流程,改写响应格式,同时保持模型验证逻辑不变。
重写 ActiveForm 的 validateAction 行为
若使用 ActiveForm::validate() 的 AJAX 验证(如失去焦点实时校验),需覆盖其默认行为:
- 在控制器中定义
actionValidate(),手动调用$model->validate() - 不调用
$this->render(),直接return $this->asJson([...]) - 确保请求是 POST + X-Requested-With: XMLHttpRequest,避免被误当普通提交
统一拦截 model save() 失败场景
API 接口通常通过 $model->load() + $model->save() 处理提交。可在基控制器中封装通用保存逻辑:
- 检查
$model->load($post)返回 false 时,立即返回['success' => false, 'errors' => $model->getErrors()] - 成功则返回
['success' => true, 'data' => $model->attributes] - 用
Response::FORMAT_JSON强制格式,避免 Content-Type 错误
全局配置验证错误消息结构
默认 $model->getErrors() 返回嵌套数组(字段 → 消息数组),前端解析不便。可封装辅助方法标准化:
- 遍历
$model->getErrors(),扁平化为['field' => 'required', 'message' => '用户名不能为空']形式 - 对多条同字段错误,用
implode(';', $messages)合并,避免前端循环渲染 - 在基模型中加
getApiErrors()方法,复用到所有表单模型
处理批量验证与自定义规则异常
涉及事务或复杂业务逻辑时,验证可能跨多个模型或需抛出异常。此时需捕获并转为 JSON:
- 用
try...catch (ValidationException $e)捕获自定义异常 - 在
catch中统一返回['success' => false, 'code' => 422, 'message' => $e->getMessage()] - 对数据库唯一约束等底层错误,用
$model->hasErrors()优先判断,避免裸抛 PDOException


















