Yii2多参数校验需严格定义验证方法签名($model, $attribute, $params),通过$params传入依赖字段或条件,并设置skipOnEmpty/skipOnError为false确保执行,否则易静默失效。

Yii2 自定义验证规则支持多参数校验,关键在于正确声明验证方法签名、合理使用 $params 传递配置,并在逻辑中结合多个字段或外部条件判断。它不是靠“多个属性写在同一规则里”实现的,而是通过验证方法内部访问其他属性或传入参数来完成协同校验。
验证方法必须接收三个固定参数
自定义验证方法(如 validatePasswordConfirm)签名必须严格为:
-
$model:当前模型实例(即
$this) - $attribute:当前被校验的字段名(由 rules 中指定)
-
$params:关联数组,用于传入额外配置(如
['on' => 'create', 'otherField' => 'password'])
漏掉 $params 或类型/顺序不对,会导致验证静默跳过,不报错也不执行。
用 $params 传入辅助字段或开关参数
当需要对比两个字段(如密码与确认密码)、或根据某字段值决定是否校验另一字段时,把依赖字段名作为参数传入:
public function rules()
{
return [
[['password_repeat'], 'validatePasswordConfirm', 'otherField' => 'password'],
[['reason'], 'validateRequiredWhenStatus', 'statusField' => 'status', 'requiredValue' => 1],
];
}
public function validatePasswordConfirm($attribute, $params)
{
$otherField = $params['otherField'] ?? 'password';
if ($this->$attribute !== $this->$otherField) {
$this->addError($attribute, '两次输入的密码不一致');
}
}
public function validateRequiredWhenStatus($attribute, $params)
{
$statusField = $params['statusField'] ?? 'status';
$requiredValue = $params['requiredValue'] ?? 1;
if ($this->$statusField == $requiredValue && empty($this->$attribute)) {
$this->addError($attribute, '状态为 ' . $requiredValue . ' 时,此项必填');
}
}
注意空值与错误状态下的执行控制
默认情况下,若字段为空或前面规则已报错,Yii 可能跳过后续验证。要确保多参数逻辑始终运行,需显式关闭跳过行为:
-
'skipOnEmpty' => false:即使字段为空也执行该验证 -
'skipOnError' => false:即使前面规则失败也继续执行
例如:
[['reason'], 'validateRequiredWhenStatus', 'statusField' => 'status', 'skipOnEmpty' => false, 'skipOnError' => false]
避免常见失效问题
多参数校验容易因以下原因失效:
- 验证方法不是
public,或命名不匹配 rules 中写的字符串 - 忘记在
rules()中以数组形式传参(不能只写'validateXxx',必须是['validateXxx', 'param1' => 'val']) - 在方法内直接用
$_POST或全局变量,而不是通过$this->xxx访问模型属性 - 未调用
$this->addError(),而用return false或抛异常 —— 这不会触发 Yii 错误收集机制











