yii2中“跳过场景”通过控制验证规则在特定场景下是否生效来实现,需显式设置模型scenario、在rules()中用'on'限定场景、用'when'动态判断或在自定义验证中主动return。

Yii2 中“跳过场景”不是靠配置开关实现的,而是通过控制验证规则是否在当前场景下生效来达成。所谓“跳过”,本质是让某条规则不参与当前场景的校验流程——它不执行、不报错、不影响其他字段。
明确场景并设置模型场景
模型默认使用 default 场景。若想让某条规则只在 register 时起作用,其余场景(如 update 或 API 调用)自动忽略,必须先确保模型实际处于目标场景:
- 控制器中显式赋值:
$model->scenario = 'register'; - 或构造时传入:
$model = new User(['scenario' => 'register']); - 模型类需定义
scenarios()方法,声明该场景允许操作哪些属性,否则load()可能不赋值
在 rules() 中用 'on' 限定规则生效场景
这是最直接的方式:不写 on 的规则对所有场景生效;写了 on 的,只在指定场景触发。
例如,头像上传只在注册时强制,编辑时不校验:
public function rules()
{
return [
[['username', 'email'], 'required'],
[['avatar'], 'required', 'on' => 'register'], // 仅 register 场景校验
[['avatar'], 'file', 'extensions' => 'jpg,png', 'on' => 'register'],
[['status'], 'in', 'range' => [0, 1]], // 所有场景都校验
];
}
用 when + skipOnEmpty 精确控制执行时机
当需要更动态的跳过逻辑(比如“只有 status=1 时才校验 phone”),可用 when 回调配合 skipOnEmpty:
-
when返回 false → 整条规则跳过,不执行任何验证 -
skipOnEmpty默认为 true,表示字段为空就跳过;设为 false 后,即使为空也走when判断
示例:仅当用户类型为 VIP 时才校验邀请码,且空值也要检查:
['invite_code', 'required',
'when' => function ($model) {
return $model->user_type === 'vip';
},
'skipOnEmpty' => false
]
自定义验证方法里主动 return 跳出
对于内联验证器或独立验证类,在方法内部可直接判断条件,不符合就提前返回,不调用 addError():
public function validateInviteCode($attribute, $params)
{
if ($this->user_type !== 'vip') {
return; // 主动跳过,不报错也不继续
}
if (!Invitation::isValid($this->$attribute)) {
$this->addError($attribute, '邀请码无效');
}
}
不需要额外配置“跳过场景”的全局开关,关键在于规则声明时绑定场景、运行时判断条件、以及模型本身正确切换场景。漏掉任一环,规则都会静默失效。











