Yii2表单错误提示中文化需三步协同:1.在attributeLabels()中定义字段中文别名;2.验证规则中用message选项或{attribute}占位符绑定中文提示;3.内联验证器中调用getAttributeLabel()动态获取别名。

在Yii2中让表单错误提示显示为中文、带字段别名、动态可变,而不是默认的英文“Username cannot be blank”,需要从模型定义、验证规则、属性标签三处协同配置,缺一不可。
给字段起中文别名
在模型类中添加 attributeLabels() 方法,返回字段名到中文名的映射数组。这个方法不是可选的——没有它,{attribute} 占位符就无法被替换成中文,后续所有自定义消息都会显示原始字段名。
public function attributeLabels() { return ['username' => '用户名', 'email' => '邮箱地址']; }
在验证规则里直接写死错误消息
这是最直白的方式,适合错误文案固定、不随上下文变化的场景。把 message 选项直接加在规则数组里,值就是你要显示的中文提示。
return [ ['username', 'required', 'message' => '用户名不能为空'], ['email', 'email', 'message' => '邮箱格式不正确'] ];
注意:message字符串里可以安全使用 {attribute} 占位符,它会自动替换成 attributeLabels() 中定义的中文名。比如上面的 username 规则触发后,实际显示的是“用户名不能为空”,而不是“username不能为空”。
用占位符实现动态错误消息
当多个字段共用同一条验证规则(比如都要求必填),又希望每个字段提示各自的名字时,必须用 {attribute} 占位符,不能写死文字。
第一步:在 rules() 中声明多字段联合验证,并绑定 message 模板
return [ [['username', 'email', 'phone'], 'required', 'message' => '{attribute}是必填项'] ];
第二步:确保 attributeLabels() 已正确定义,否则 {attribute} 不会被替换,用户看到的就是“username是必填项”这种原始字段名。
第三步:验证失败后,每个字段会各自渲染对应中文名+模板,例如“用户名是必填项”“邮箱地址是必填项”“手机号是必填项”。这比写三条重复规则更简洁,也避免漏改某一条。
在内联验证器里动态生成错误消息
内联验证器适合逻辑复杂、需读取其他字段或执行数据库查询的校验,比如“密码确认必须与密码一致”。它的错误消息不能靠 rules() 里的 message 选项统一控制,必须在验证方法内部调用 addError() 时手动拼接。
方法一:静态消息
['password_confirm', function ($model, $attribute) { if ($model->password_confirm !== $model->password) { $model->addError($attribute, '确认密码与密码不一致'); } }]
方法二:动态拼接(推荐)
['password_confirm', function ($model, $attribute) { if ($model->password_confirm !== $model->password) { $label = $model->getAttributeLabel($attribute); $model->addError($attribute, $label . '与密码不一致'); } }]
这里用了 $model->getAttributeLabel($attribute) 主动获取中文别名,比硬编码更健壮——字段名改了,提示文案自动同步,不用翻遍代码找字符串。
全局覆盖默认验证消息
如果项目中大量使用 email、required、integer 等内置验证器,又不想每条规则都写 message,可以在 config/web.php 的 components 下配置 validator 组件的 messages 属性。
'components' => [
'validator' => [
'class' => 'yii\validators\Validator',
'messages' => [
'required' => '{attribute}不能为空',
'email' => '{attribute}格式不正确',
'integer' => '{attribute}必须是整数'
]
],
]
这个配置对所有模型生效,但注意:它只影响未显式指定 message 的规则。一旦某条规则写了 'message' => 'xxx',就会优先用这条,跳过全局配置。


















