Yii2控制器统一处理表单验证并返回标准JSON响应,需三步:一是在控制器基类beforeAction中拦截验证失败并返回400状态码及errors结构;二是禁用HTML错误页,通过配置errorHandler或继承yii\rest\Controller;三是配置JsonParser支持application/json请求体解析。

Yii2控制器要统一处理表单验证并返回标准JSON响应,核心在于三件事:让验证失败时自动走JSON流程、避免HTML错误页干扰、确保返回结构一致且状态码准确。不靠每个action手动判断,而是通过配置和基类收口。
在控制器基类中统一拦截验证失败
继承 yii\rest\Controller 或自定义基类,在 beforeAction() 中检查模型验证结果。若控制器内有调用 $model->validate() 且失败,立即终止后续逻辑,主动返回JSON错误:
- 检查
$model->hasErrors(),有则调用response->setStatusCode(400) - 构造标准结构:
['code' => 400, 'message' => '参数校验失败', 'errors' => $model->getErrors()] - 设格式:
Yii::$app->response->format = Response::FORMAT_JSON
让验证异常不跳转到site/error HTML页面
默认情况下,throw new BadRequestHttpException() 或验证失败后未显式处理,会落入全局 errorAction 并渲染HTML。需切断这个路径:
- 在
config/web.php的errorHandler配置中,把errorAction设为空字符串或注释掉(API模块不用它) - 确保 API 控制器没继承
yii\web\Controller,优先用yii\rest\Controller—— 它默认禁用HTML错误页 - 不要在 action 中写
if (!$model->validate()) { throw new BadRequestHttpException(); },而是自己 return JSON
响应结构与状态码必须匹配
很多人 return 数组后发现 HTTP 状态码还是 200,是因为 Yii 默认不改状态码。必须显式设置:
- 验证失败 →
Response::STATUS_BAD_REQUEST (400) - 模型不存在(如更新不存在的ID)→
Response::STATUS_NOT_FOUND (404) - 权限不足 →
Response::STATUS_FORBIDDEN (403) - 所有情况都应在 return 前执行
Yii::$app->response->setStatusCode($code)
配合请求解析器,让 post() 能直接读 JSON 字段
前端发的是 Content-Type: application/json,但默认 $request->post('username') 拿不到。需提前配置解析器:
- 在
config/web.php的components.request.parsers中添加:'application/json' => 'yii\web\JsonParser' - 之后
$model->load(Yii::$app->request->post(), '')就能正常绑定 JSON 数据 - 避免再用
getRawBody()+json_decode()手动解析,减少出错点


















