Yii2 API验证失败需返回标准JSON格式错误,应在Controller中调用$model->validate()后返回$model->errors并设response format为JSON,或全局配置ApiExceptionHandler统一处理,响应状态码应为422且结构为{"status":422,"message":"验证失败","errors":{...}}。

Yii2 API 表单验证失败时,默认会返回 HTML 错误页面,这在前后端分离的 API 场景中完全不适用。要让验证错误以标准 JSON 格式返回(如 {"name": ["姓名不能为空"], "email": ["邮箱格式不正确"]}),需统一拦截验证异常并重写响应逻辑。
重写 ActiveForm::validate() 的返回行为
API 场景下通常不使用 ActiveForm 的客户端验证,而是直接调用模型的 validate() 方法。关键在于:验证失败后不要渲染视图,而是主动构造 JSON 响应:
- 在 Controller 中手动调用
$model->validate() - 验证失败时,用
$model->getErrors()获取字段级错误数组 - 调用
Yii::$app->response->format = Response::FORMAT_JSON - 直接
return $model->errors(Yii2 会自动序列化为 JSON)
全局捕获 ValidationException(推荐)
更健壮的方式是统一处理所有验证失败场景,包括批量赋值(load() + validate())、RESTful 操作等。可在 config/web.php 中配置全局异常处理器:
- 自定义
ApiExceptionHandler类,继承yii\web\ErrorHandler - 重写
renderException(),对yii\base\InvalidParamException和yii\base\ModelEvent相关验证异常做特殊处理 - 检测到模型验证失败时,提取
$exception->getMessage()或遍历关联模型的getErrors() - 设置响应格式为 JSON,并返回结构化错误体(含 status、message、errors 字段)
使用 RestController 时的注意事项
若继承 yii\rest\Controller,默认已支持 JSON 响应,但验证错误仍可能触发 HTML 页面。需确保:
- 控制器类中未覆盖
beforeAction()并意外修改了 response format - 模型验证失败后,不调用
$this->render()或类似视图方法 - 在
actions()配置中,对create、update等动作启用'class' => 'yii\rest\CreateAction'等标准动作类,它们内部已处理验证失败并返回 JSON - 若自定义动作逻辑,务必在
if (!$model->validate()) { return $model->errors; }后立即 return,避免后续执行
前端友好:统一错误结构与状态码
单纯返回 $model->errors 不够规范。建议封装成标准 API 错误格式:
- HTTP 状态码设为
422 Unprocessable Entity(语义最贴切) - 响应体示例:
{"status": 422, "message": "验证失败", "errors": {"email": ["邮箱已被注册"]}} - 可封装一个
apiResponse()工具方法,在验证失败时统一调用:return ['status' => 422, 'message' => '验证失败', 'errors' => $model->errors];


















