yii2 api验证失败应抛unprocessableentityhttpexception异常并统一json响应,需配置errorhandler、禁用html错误页、确保accept头为application/json。

Yii2 中 Model 验证失败时,默认会返回 HTML 错误页或空响应,这对 API 接口完全不适用。要让验证异常(如 422 Unprocessable Entity)统一输出结构清晰的 JSON,关键不是改视图,而是拦截验证流程、接管错误响应、并规范数据格式。
验证失败时自动转为 JSON 响应
当模型调用 $model->validate() 或 $model->save() 失败,Yii 通常只把错误存在 $model->errors 中,但不会主动抛异常。你需要在控制器中主动判断并触发标准异常:
- 手动检查验证结果:若
!$model->validate(),立即抛出\yii\web\UnprocessableEntityHttpException - 避免直接
return ['success'=>false, 'data'=>$model->errors]—— 这会导致状态码仍是 200,且绕过全局错误处理器 - 推荐写法:
throw new \yii\web\UnprocessableEntityHttpException('Validation failed', 422);
统一捕获并格式化验证错误
仅抛异常还不够,必须确保它被正确序列化为 JSON。需配合自定义错误处理器:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 在
config/web.php的components中配置errorHandler,指定errorAction指向一个纯 JSON 响应动作(如'site/error') - 在
SiteController::actionError()中,获取异常并提取验证错误:$exception->getName()判断是否为UnprocessableEntityHttpException,再从$model(若可访问)或上下文里取出$errors - 返回标准结构:
['success'=>false, 'data'=>['errors'=>$errors]],同时显式设置状态码:Yii::$app->response->setStatusCode(422)
让 REST 控制器自动处理验证异常
如果你使用的是 yii\rest\ActiveController 或 yii\rest\Controller,框架已内置支持:
- 重写
beforeAction(),在调用父类前检查模型验证,失败则抛UnprocessableEntityHttpException - 确保控制器行为中启用了
ContentNegotiator,明确声明'application/json' => Response::FORMAT_JSON - REST 模块会自动将
422异常映射为 JSON,并附带"name": "Unprocessable Entity"和字段级错误信息
避免常见陷阱
很多项目卡在“明明写了 JSON 输出,但前端收到的还是 HTML 或空内容”,问题往往出在:
- 没禁用默认 HTML 错误页:确认
YII_DEBUG = false,且未启用catchAll或覆盖了errorHandler - 请求头缺失
Accept: application/json:API 客户端(如 curl、Postman)需显式带上,否则 Yii 可能回退到 HTML 渲染 - 在
action中先 echo / var_dump / 使用了exit:这会提前发送响应头,导致后续设状态码或格式失效










