yii2自定义验证器需按场景选择:内联验证器用于简单逻辑,签名固定为function($model,$attribute,$params),失败调用adderror;独立验证类继承yii\validators\validator,类名须以validator结尾,支持客户端验证和参数配置。

Yii2 自定义验证器组件实现通用参数校验,核心在于区分使用场景:简单逻辑用内联验证器,复用性强或需配置的逻辑必须封装为独立验证类。关键不是“能不能写”,而是“怎么写才稳定、可维护、支持扩展”。
内联验证器:适合字段间联动或一次性判断
直接在 rules() 中用匿名函数或模型方法名声明,无需额外类文件。
- 签名固定为
function($model, $attribute, $params),三个参数缺一不可 - 失败时必须调用
$model->addError($attribute, $message),不能 return false 或 throw 异常 - 若字段允许为空(没加
required),内联验证默认仍会执行;如需跳过空值,手动加判断:if (empty($model->$attribute)) return; - 写法只能是
['field', function () {}]或['field', [$this, 'methodName']],不能只写字符串'methodName'
独立验证类:适合手机号、身份证、自定义格式等通用校验
新建 PHP 类继承 yii\validators\Validator,重写 validateAttribute() 方法。
- 类名必须以
Validator结尾(如MobileValidator),否则自动加载失败 - 务必在
init()中调用parent::init(),否则$this->message等属性未初始化 - 参数通过 public 属性声明(如
public $strict = true;),并在 rules 中传入:['mobile', 'MobileValidator', 'strict' => false] - 如需客户端验证,实现
clientValidateAttribute(),返回合法 JS 字符串(注意单双引号转义)
绕过空值和错误跳过的常见陷阱
默认情况下,验证器遇到空值(skipOnEmpty)或前序规则已报错(skipOnError)会跳过执行。若你希望自定义规则始终生效(比如依赖其他字段状态的条件校验),需显式关闭:
['field', 'MyValidator', 'skipOnEmpty' => false, 'skipOnError' => false]- 内联验证同理:
['field', function () {}, 'skipOnEmpty' => false] - 不设这两项,当字段为空或已有错误时,你的校验逻辑根本不会运行
验证器与场景(scenario)配合使用
不同业务流程对同一模型有不同校验要求,例如注册要验邮箱,登录则不需要。可通过 on 指定适用场景:
['email', 'email', 'on' => 'signup']- 同时支持多个场景:
['email', 'email', 'on' => ['signup', 'reset']] - 场景需在
scenarios()中明确定义活动属性,否则load()可能不赋值











