yii2自定义验证需明确null是否合法:允许时在验证方法开头return,不允许则adderror;推荐结合skiponempty/skiponnull规则配置及重写isempty()精细控制。

Yii2 中自定义验证规则遇到参数为 null 时,默认不会自动跳过验证(除非显式配置 skipOnEmpty 或字段本身允许为空),容易导致空值校验失败或抛出异常。关键在于明确「null 是否合法」,再选择合适的处理方式。
确认字段是否允许为 null
先检查数据库字段定义和模型规则中是否允许空值:
- 若数据库字段设为
NULL,且业务逻辑允许空值,应在rules()中添加'allowEmpty' => true或使用'required'规则控制必填性 - 若字段不允许为
null(如主键、外键、非空约束),则应在自定义验证方法中主动拦截并报错 - 注意:
skipOnEmpty默认为true,但仅对空字符串、null、[]等生效;若你重写了验证逻辑却没判断null,它仍会进入你的方法
在自定义验证方法中安全判断 null
推荐在验证方法开头显式处理 null,避免后续操作(如调用字符串方法、数组访问)出错:
public function validateCustomField($attribute, $params)
{
$value = $this->$attribute;
// 允许 null:直接返回,不报错
if ($value === null) {
return;
}
// 不允许 null:手动加错误
if ($value === null) {
$this->addError($attribute, '该字段不能为空');
return;
}
// 正常校验逻辑(此时 value 已确定非 null)
if (!is_string($value) || strlen($value) addError($attribute, '长度不能少于3个字符');
}
}
配合 rules() 配置 skipOnEmpty 和 on 场景
更规范的做法是结合规则配置,让框架帮你过滤掉不需要验证的空值:
-
'skipOnEmpty' => true:当值为null、''、[]时跳过当前规则(默认已开启) -
'skipOnNull' => true(Yii2.0.38+):专门跳过null,不影响空字符串校验 - 搭配场景使用,例如只在
'update'时允许空,'create'时强制非空:
['custom_field', 'app\validators\CustomValidator', 'on' => 'create', 'skipOnEmpty' => false], ['custom_field', 'app\validators\CustomValidator', 'on' => 'update', 'skipOnNull' => true],
使用独立验证器类并重写 isEmpty()
若需精细控制「什么算空」,可继承 Validator 并重写 isEmpty() 方法:
class CustomValidator extends Validator
{
protected function isEmpty($value)
{
// 仅把 '' 和 [] 当作空,保留 null 进入 validateValue()
return $value === '' || $value === [];
}
protected function validateValue($value)
{
if ($value === null) {
return ['该字段不能为 null', []];
}
if (!is_numeric($value)) {
return ['必须为数字', []];
}
return null;
}
}
不复杂但容易忽略:null 的语义要和业务对齐,验证前先想清楚——它是「未填写」、「不适用」还是「非法输入」?选对策略比硬写 if 判断更重要。











