yii2自定义验证器需继承yii\validators\validator,声明public属性作为可配置参数,在validateattribute()中实现校验逻辑,类名以validator结尾,rules()中传参需与属性名完全一致。

Yii2 创建独立自定义参数验证器,核心是定义一个继承 yii\validators\Validator 的类,通过 public 属性暴露可配置参数,并在 validateAttribute() 中使用这些参数完成校验逻辑。
定义验证器类并声明参数
参数必须声明为 public 属性,不能藏在 $params 里解析。框架会自动把 rules() 中传入的键值对赋给同名属性。
- 类名必须以 Validator 结尾(如
PhoneValidator),否则自动加载失败 - 必须重写
validateAttribute($model, $attribute),不是validate() - 构造函数中记得调用
parent::__construct($config)或在init()中调用parent::init(),否则$this->message等基础属性为空
示例:带区号校验的手机号验证器
use yii\validators\Validator;
class PhoneValidator extends Validator
{
public $countryCode = '86'; // 可配置参数,默认中国
public $strict = false; // 是否启用严格格式(如11位+前缀)
public function init()
{
parent::init();
if ($this->message === null) {
$this->message = '{attribute} 不是有效的手机号。';
}
}
public function validateAttribute($model, $attribute)
{
$value = $model->$attribute;
if (!is_string($value)) {
$this->addError($model, $attribute, $this->message);
return;
}
$value = trim($value);
if (empty($value)) return;
$pattern = $this->strict
? '/^' . preg_quote($this->countryCode, '/') . '\d{11}$/'
: '/^' . preg_quote($this->countryCode, '/') . '\d{10,12}$/';
if (!preg_match($pattern, $value)) {
$this->addError($model, $attribute, $this->message);
}
}
}
在模型 rules() 中使用并传参
直接写类的完整命名空间路径,然后以键值对形式传入参数:
public function rules(){
return [
['mobile', 'app\validators\PhoneValidator', 'countryCode' => '1', 'strict' => true],
['backup_phone', 'app\validators\PhoneValidator', 'countryCode' => '44'],
];
}
- 参数名必须与验证器类中的 public 属性名完全一致(大小写敏感)
- 未传的参数将使用类中定义的默认值
- 不支持在 rules() 中动态计算参数值(如
'countryCode' => $this->regionCode),只能是静态值或常量
支持客户端验证(可选)
若需表单失去焦点时实时校验,必须实现 clientValidateAttribute() 方法,返回合法 JavaScript 字符串:
{
$options = json_encode([
'countryCode' => $this->countryCode,
'strict' => $this->strict,
'message' => $this->formatMessage($this->message, [
'attribute' => $model->getAttributeLabel($attribute),
]),
], JSON_UNESCAPED_UNICODE);
return if (value !== '' && !/^\$countryCode\d{10,12}$/.test(value)) {
messages.push($options.message);
}
JS;
}
- 注意 JS 中要正确转义变量,推荐用
json_encode()构造配置对象 - 实际正则需根据 PHP 端逻辑同步调整,避免前后端校验不一致
- 若不实现该方法,此验证器仅在服务端生效
注意事项与常见陷阱
几个高频出错点务必避开:
- 忘记在
init()中调用parent::init()→ 导致$this->message、$this->on、$this->when等全为空 - 误写
validate()而非validateAttribute()→ 验证永远不会触发 - 参数名拼写错误或大小写不符 → 传参失效,始终用默认值
- 类文件未按 PSR-4 规范放置,或命名空间与路径不匹配 → 类找不到
- 没设
'skipOnEmpty' => false却期望校验空字符串 → 空值被跳过,不执行validateAttribute()











