Yii2自定义验证器支持通过外部参数动态控制校验逻辑,内联验证器用$params接收参数,独立类通过public属性声明并init()中调用parent::init()注入,参数可用于validateAttribute、when、skipOnEmpty等场景。

Yii2 自定义验证器支持通过 外部参数 动态控制校验逻辑,比如传入最小长度、白名单数组、关联模型字段名等。关键在于正确声明参数、传递参数,并在验证过程中安全使用。
内联验证器中使用外部参数
内联验证器用匿名函数或方法回调定义,第三个参数 $params 就是专门接收外部参数的入口。
- 规则写法示例:
['mobile', function ($model, $attribute, $params) { ... }, 'pattern' => '/^1[3-9]\d{9}$/', 'message' => '手机号格式不正确'] -
$params是一个关联数组,里面包含你在规则中直接写的键值对(如'pattern'和'message') - 可直接读取:
$pattern = $params['pattern'] ?? '/^\d{11}$/';,建议加空合并避免报错 - 错误提示也推荐用
$params['message'] ?? '默认提示',方便复用时覆盖 - 注意:不能省略第三个参数,即使不使用也要保留占位符
独立验证类中声明并使用外部参数
独立验证类通过 public 属性声明参数,Yii2 会自动注入 rules 中传入的值。
- 在类中定义:
public $minLength = 6;、public $allowEmpty = true; - 必须在
init()中调用parent::init(),否则参数不会生效 - 规则写法:
['password', 'PasswordValidator', 'minLength' => 8, 'allowEmpty' => false] - 在
validateAttribute()中直接使用$this->minLength即可 - 若参数需校验合法性(如
$minLength必须为正整数),可在init()中做判断并抛出InvalidConfigException
结合 when 或 skipOnEmpty 使用参数
外部参数还可参与条件控制逻辑,让验证更灵活。
-
when支持闭包,可读取参数:'when' => function ($model) { return $model->type === 'vip'; },但注意闭包内无法直接访问$this,需把参数提前存到模型属性或用 use 传入 -
skipOnEmpty可设为布尔值或回调,例如:'skipOnEmpty' => function ($model) { return $model->skipValidation === true; } - 当
when和skipOnEmpty同时存在时,先执行when判断是否运行验证,再由skipOnEmpty决定空值是否跳过
常见陷阱与建议
参数传递看着简单,但容易因初始化时机或作用域问题出错。
- 独立类中忘记写
public $xxx;声明 → 参数不会被注入,始终为 null - 内联验证器里误把
$params当成模型属性读取 → 应该用$params['key']而非$model->key - 参数名和内置属性冲突(如
message、on、except)→ Yii2 会优先处理这些保留键,自定义参数建议加前缀,如customMessage - 客户端验证需同步参数:若实现
clientValidateAttribute(),JS 字符串中要手动拼入参数值,例如:"if (value.length minLength}) { messages.push('{$this->message}'); }"


















