验证器需显式调用check()才生效,必须用php think make:validate生成类文件,控制器中validate()仅返回对象,须链式调用check();字段名严格匹配、开启batch(true)才能获取全部错误,scene()必须显式调用才过滤字段。

验证器在 ThinkPHP 8.0 中不是“写完规则就自动生效”的开关,而是必须显式调用 check() 才真正执行校验;不调用、字段名不一致、没捕获异常或忽略 batch(true) 的返回结构,都会导致验证形同虚设。
验证器类怎么创建才不报 Class not found
别手动建文件。直接用命令行生成,路径、命名空间、继承关系全由框架保证:
-
php think make:validate UserValidate→ 自动生成app/validate/UserValidate.php - 手动创建时,必须确认:
namespace app\validate;+use think\Validate;+ 类名与文件名严格一致(UserValidate不是user_validate) - 常见错误:
Class 'app\validate\UserValidate' not found,90% 是文件放错目录(比如丢进了app/controller/或application/)或命名空间拼错
控制器里调用 validate() 为什么没反应
因为 validate() 门面只是返回一个验证器对象,不调 check() 就等于只拿了安检仪没按启动键:
- 正确写法:
validate(UserValidate::class)->check($data),失败抛ValidateException,必须try/catch - 若想自己处理布尔结果,改用实例化:
(new UserValidate())->check($data),返回true/false,错误信息从getError()拿 - 字段名必须和
$data数组的 key 完全一致(区分大小写),$rule['user_name']对应$data['user_name'],写成username就跳过校验
为什么只报一个错,而不是所有字段的错误
默认是短路模式:第一个字段失败就终止。要一次性看到全部问题,必须主动开启批量验证:
立即学习“PHP免费学习笔记(深入)”;
- 加
->batch(true):如validate(UserValidate::class)->batch(true)->check($data) - 注意:
getError()此时返回的是数组(['email' => '邮箱格式错误', 'name' => '姓名不能为空']),不是字符串;直接echo或json_encode未处理的数组会出错 - 前端需要单条提示?自己做聚合:
implode(';', $validator->getError())
场景(scene)为什么设了却没过滤字段
设了 $scene 属性只是定义白名单,不调 scene() 方法就不会生效:
- 在验证器类中声明:
protected $scene = ['register' => ['name', 'email', 'password']] - 调用时必须显式指定:
(new UserValidate())->scene('register')->check($data) - 用门面方式也一样:
validate(UserValidate::class)->scene('register')->check($data) - 漏掉
scene()调用,验证器仍会校验$rule中所有字段,和没设场景一样
最容易被忽略的是:batch(true) 后 getError() 返回结构突变,以及 scene() 必须显式调用——这两点不注意,调试时会反复怀疑规则写错了,其实只是调用链断在了中间。



















