yii2控制器处理表单应先load()再显式validate(),ajax请求用response::format_json返回统一结构:成功时'success'=>true,失败时'success'=>false并附geterrors()字段错误。

在 Yii2 中,控制器处理表单提交并返回 JSON 响应时,验证失败应返回结构清晰的错误信息,验证成功则返回成功状态。关键在于:调用 $model->load() 后必须调用 $model->validate(),不能只依赖 load() 的返回值判断是否有效。
基础 JSON 验证返回写法
适用于普通 Ajax 表单提交(如登录、注册、留言):
- 使用
Yii::$app->request->isAjax判断是否为 Ajax 请求 -
$model->load()加载数据后,务必显式调用$model->validate() - 验证失败时,用
$model->getErrors()获取字段级错误,返回统一 JSON 结构 - 避免直接 echo 或使用
Json::encode()手动输出,推荐用Yii::$app->response->format = Response::FORMAT_JSON
示例代码:
use yii\web\Response;
public function actionLogin()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// 登录逻辑,如生成 token、设置 session 等
return ['success' => true, 'message' => '登录成功'];
} else {
return [
'success' => false,
'errors' => $model->getErrors(),
];
}
}
带事务和自定义错误字段名的写法
当需要兼容前端字段映射(如前端用 user_email,模型属性是 email),或需在验证后执行数据库操作时:
- 可在控制器中手动重映射错误键名,例如将
'email'→'user_email' - 若涉及多模型或写库操作,建议包裹在
Transaction中,并在异常时统一返回错误 - 不建议在
validate()前做业务校验,应统一放在模型的rules()或beforeValidate()
前端接收示例(JavaScript)
配合上述返回格式,前端可这样处理:
$.post('/site/login', formData)
.done(function(res) {
if (res.success) {
alert(res.message);
location.href = '/dashboard';
} else {
// 显示各字段错误,如 res.errors.email[0]
Object.keys(res.errors).forEach(field => {
const msg = res.errors[field][0] || '输入有误';
$(`[name="${field}"]`).next('.error').text(msg);
});
}
});
注意事项
- 确保模型的
scenarios()和rules()正确配置,特别是不同请求场景(如 create/update)使用不同场景 - 若表单含文件上传,
load()不会自动处理,需额外调用$model->upload()类方法 - 禁用 CSRF 验证时(仅限 API 场景),应在控制器加
public $enableCsrfValidation = false;,但生产环境慎用 - 调试时可用
var_dump($model->getErrors()); die;快速确认验证是否触发











