Yii2 rules()支持内联和独立验证器:内联适用于简单条件校验,需手动处理空值与addError;独立验证器需继承Validator、声明参数属性并实现validateAttribute,支持复用与客户端验证。

Yii2 的 rules() 支持灵活配置自定义参数验证器,关键在于区分使用场景:简单逻辑用内联方式,复用性强或带配置项的用独立验证类。下面给出两种典型、可直接运行的实例。
内联验证器:带参数的字段间校验
适用于如“当 status=1 时,reason 必填”这类条件校验。参数通过 $params 传入,签名固定,且需手动处理空值跳过逻辑:
- 在
rules()中写成数组回调形式:['reason', function ($model, $attribute, $params) { ... }],不能只写方法名 -
$params可携带任意键值,比如['reason', 'requiredIf', 'when' => 'status', 'value' => 1],但此时需自己实现判断逻辑 - 若字段本身允许为空(无
required规则),默认仍会执行验证;想跳过空值,需加判断:if ($model->status != 1 || $model->$attribute === null || $model->$attribute === '') return; - 失败时必须调用
$model->addError($attribute, $message),不能return false或抛异常
独立验证类:支持配置参数的复用型校验
适合需要传参、多处复用的场景,例如校验手机号是否符合某地区规则、密码强度分级等。类需继承 yii\validators\Validator,并规范命名和初始化:
- 类名必须以
Validator结尾,如MobileValidator,否则自动加载失败 - 在
init()中务必调用parent::init(),否则$this->message等属性为空 - 参数通过 public 属性声明,例如
public $country = 'CN';,然后在 rules 中传入:['mobile', 'MobileValidator', 'country' => 'US'] -
validateAttribute()是核心方法,接收$model和$attribute,内部用$model->$attribute取值校验
客户端验证补充(可选)
若需表单失焦时也触发 JS 校验,独立验证类还需实现 clientValidateAttribute() 方法,返回合法 JS 字符串。注意引号转义,例如返回:"if (value !== 'admin') { messages.push('必须是 admin'); }"。内联验证器不支持客户端验证,必须配合 AJAX 验证使用。
常见失效原因与修复
自定义规则不生效,多数因以下两点:
-
skipOnEmpty默认为true,字段为空时直接跳过;如需强制校验(比如空字符串也要检查格式),显式设为false -
skipOnError默认为false,但若前面规则已报错(如required失败),后续规则默认不再执行;需设为false才保证始终运行 - 验证方法签名错误,比如漏掉
$params参数,或把function ($model, $attribute)写成function ($attribute)


















