Yii2自定义验证不执行的最常见原因是数据未加载进模型——需先调用load()再validate();场景未匹配、自定义方法执行条件未满足、规则未正确挂载也会导致验证失效。

Yii2自定义验证不执行,**最常见原因是数据根本没进模型**——验证器根本没机会运行。不是规则写错了,而是验证压根没被触发。
数据没加载进模型
这是头号原因。`$model->validate()` 只校验当前模型已有的属性值,不会自动从请求中取数据。
- 必须先调用 `$model->load($request->post())` 或 `$model->load($request->getBodyParams(), '')`,再调用 `validate()`
- 表单字段名带 model 前缀(如
user[username])时,`load()` 默认能识别;若前端发的是扁平结构(如{"username":"a"}),第二个参数必须传空字符串:$model->load($data, '') - JSON 请求需手动解析:
$raw = $request->getRawBody(); $data = Json::decode($raw); $model->load($data, ''),否则 `load()` 返回 false,但你不检查就直接 `validate()`,结果永远“通过”
场景(scenario)没配对
规则写了 `on => 'create'`,但场景没激活,那这条规则就完全被忽略。
- 模型类中必须显式定义
scenarios()方法,返回字段白名单,例如:return ['create' => ['name', 'email']] - 规则里指定了
on,控制器中就必须有$model->scenario = 'create',且这行代码要在load()和validate()之间 - 没写
on的规则才对所有场景生效;只写on却漏掉其他环节,等于没写
自定义方法未满足执行条件
Yii 默认跳过空值和已有错误的字段,你的验证方法可能被提前拦下了。
- 字段为空时,默认不执行验证逻辑。若需强制校验(比如判断空字符串是否合法),必须加
'skipOnEmpty' => false - 该字段前面已有其他规则报错(如必填失败),默认也会跳过后续验证。需要加
'skipOnError' => false才继续执行 - 自定义方法必须是
public,签名严格为function ($attribute, $params);若用内联方式,必须用匿名函数或[$this, 'methodName'],不能只写字符串'methodName'
规则本身没挂载成功
尤其是动态添加或复用类验证器时,容易卡在初始化环节。
- 独立验证类名必须以
Validator结尾(如IDCardValidator),否则 Yii 自动加载失败 - 必须继承
yii\validators\Validator并重写validateAttribute();只写validate()没用 - 用
addRule()动态加规则时,必须同步设置$model->scenario,且该模型必须是新实例(new User()),不能是findOne()加载的 ActiveRecord 实例


















