在yii2中,自定义验证器应继承validator并重写validateattribute方法,通过$model->adderror()添加错误;该方法专用于单属性验证,不需调用父类方法,且$message不会自动生效。

在 Yii2 中,自定义验证器重写 validateAttribute 方法,核心是让验证逻辑直接作用于单个属性,并通过 $model->addError() 添加错误信息。
继承 Validator 并重写 validateAttribute
最常用的方式是继承 yii\validators\Validator,然后覆盖 validateAttribute 方法。该方法接收两个参数:$model(当前模型实例)和 $attribute(待验证的属性名)。
- 不要调用
parent::validateAttribute(),除非你希望保留父类默认行为(通常不需要) - 获取属性值用
$model->$attribute或$model->getAttribute($attribute) - 验证失败时,调用
$model->addError($attribute, $message)记录错误 - 验证通过则无需额外操作,框架会自动继续后续流程
示例:手机号格式验证器
下面是一个简单但实用的自定义手机号验证器:
namespace app\validators;
use yii\validators\Validator;
class PhoneValidator extends Validator
{
public function validateAttribute($model, $attribute)
{
$value = $model->$attribute;
// 简单匹配 11 位数字,以 1 开头
if (!is_string($value) || !preg_match('/^1[3-9]\d{9}$/', $value)) {
$this->addError($model, $attribute, '{attribute} 不是有效的手机号');
}
}
}
在模型中使用:
public function rules()
{
return [
[['phone'], 'app\validators\PhoneValidator'],
];
}
注意 validate() 和 validateAttribute() 的区别
validateAttribute() 是针对单个属性设计的,被框架在批量验证时自动调用;而 validate() 是面向整个模型的入口方法,通常用于需要跨属性校验(如密码确认、日期范围等)的场景。
- 若只需校验一个字段,优先用
validateAttribute - 若需同时访问多个属性(如
password和confirm_password),应重写validate()并在其中调用$model->addError() - 重写
validateAttribute时,$this->message默认不会自动生效,需手动传入错误消息
支持客户端验证(可选)
如果希望前端也执行相同逻辑,可同时实现 clientValidateAttribute() 方法,返回 JavaScript 字符串。不过多数简单规则建议交由 HTML5 或专用 JS 库处理,避免重复维护。











