启用yii2验证日志需配置log组件的validation类别filetarget,validate后主动记录错误详情,或重写基类validate方法自动埋点,敏感字段避免全量记录。

当Yii2模型验证失败却无法定位具体哪条规则、哪个字段、什么值触发了错误时,需要把验证过程完整记入日志供排查。
启用验证日志的前置配置
确保 config/web.php(或 console.php)中 log 组件已启用且 targets 至少含一个 FileTarget 或 DbTarget。若未配置,验证日志将完全丢失,【log 组件必须在 bootstrap 阶段加载】,否则验证过程中的日志调用会被静默丢弃。
在 components → log → targets 中添加一条专用于验证的日志目标:
```php
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['info'],
'categories' => ['validation'],
'logFile' => '@app/runtime/logs/validation.log',
'flushInterval' => 1,
'exportInterval' => 1,
],
]
注意:categories 必须明确写 'validation',后续手动打点才能命中该 target;flushInterval 和 exportInterval 设为 1 是为了验证失败时立刻落盘,避免请求结束前日志丢失。
在模型 validate() 后主动记录验证结果
这是最直接、可控性最强的方法。在控制器或服务层调用 $model->validate() 后,立即判断并记录:
方法一:只记录失败详情(推荐用于生产环境)
```php
if (!$model->validate()) {
Yii::info([
'model' => get_class($model),
'scenario' => $model->scenario,
'errors' => $model->getErrors(),
'attributes' => $model->getDirtyAttributes(),
], 'validation');
}
方法二:无论成功失败都记录(适合调试阶段)
```php
Yii::info([
'model' => get_class($model),
'scenario' => $model->scenario,
'valid' => $model->validate(),
'errors' => $model->getErrors(),
'attributes' => $model->getAttributes(),
], 'validation');
这一步操作起来很简单,直接把数组传给 Yii::info 即可。但要注意:getDirtyAttributes() 只返回被修改过的字段,若想看全部输入值,改用 getAttributes();getErrors() 返回的是二维数组,日志组件会自动转成可读字符串。
重写模型 validate 方法实现自动埋点
适用于需全局统一记录所有模型验证行为的场景,无需每处调用都加日志语句。
第一步:在基类 Model(如 common\models\Model)中重写 validate()
```php
public function validate($attributeNames = null, $clearErrors = true)
{
$result = parent::validate($attributeNames, $clearErrors);
Yii::info([
'model' => static::class,
'scenario' => $this->scenario,
'valid' => $result,
'errors' => $result ? [] : $this->getErrors(),
], 'validation');
return $result;
}
第二步:确保所有业务模型继承该基类,而非直接继承 \yii\db\ActiveRecord。
⚠️ 警告:不要在重写的 validate() 中调用 $this->getAttributes() 并记录全部字段值——若模型含大量字段或敏感字段(如 password_hash),会导致日志膨胀甚至泄露;仅在 debug 环境下临时开启。
捕获验证规则执行过程(高级调试)
当怀疑某条自定义验证规则逻辑异常,或规则未按预期触发时,可在规则方法内打点:
① 在 rules() 数组中定义规则时,使用匿名函数方式绑定上下文:
```php
public function rules()
{
return [
['email'], 'required'],
['email'], function ($attribute) {
Yii::debug("验证邮箱格式: {$this->$attribute}", 'validation.rule');
if (!filter_var($this->$attribute, FILTER_VALIDATE_EMAIL)) {
$this->addError($attribute, '邮箱格式不正确');
}
}
];
}
② 对于独立的验证器类(如 EmailValidator 子类),在其 validateAttribute() 方法开头加入 Yii::debug。
③ 若需查看所有内置规则是否被触发,可在 vendor/yiisoft/yii2/validators/Validator.php 的 validateAttribute() 方法中临时加日志——但切勿提交到生产代码,仅限本地调试。











