验证器必须是类而非规则数组,以支持场景、消息复用和自定义规则;需继承think\validate,命名与路径一致;$rule与$message键名严格对应;验证码、数组字段、场景验证须在类内实现;控制器中应实例化验证器并显式调用check()。

验证器必须写成类,不能只传规则数组;否则丢失场景、消息复用、自定义规则等关键能力。
验证器类怎么生成和存放
用命令行生成最省事,路径和命名会自动对齐命名空间:
-
php think make:validate User→ 生成app/validate/User.php -
php think make:validate admin/User→ 生成app/validate/admin/User.php -
php think make:validate admin@User→ 生成app/admin/validate/User.php
手动创建也行,但必须继承 think\Validate,且类名要和文件路径一致(如 app\validate\User 对应 User.php),否则 validate(User::class) 会找不到类。
rule 和 message 怎么配才不踩坑
$rule 定义校验逻辑,$message 定义提示语,二者字段键名必须严格对应:
- 写
'name' => 'require|max:25',就要配'name.require' => '名称必须'和'name.max' => '最多25个字符' - 如果用了别名(如
'name|用户名' => 'require'),错误提示里显示的是“用户名”,但$message键仍得用'name.require',不是'用户名.require' - 没配
$message时走系统默认提示,中文项目基本不可用,比如"name must be between 1 and 25"
注意:$message 是关联数组,键名拼错或漏写某条,对应规则失败时就显示空字符串或默认英文。
验证码、数组字段、场景验证怎么写进验证器
这些是高频但易错的扩展点,必须写在验证器类内部:
- 验证码规则直接写
'vercode' => 'require|captcha',前提是已安装topthink/think-captcha且Session已启用(否则captcha_check()永远返回false) - 数组字段(如
tags[])逐项校验,用'tags.*' => 'max:20|alphaNum';若还要限制数组长度,再加一行'tags' => 'array|each:alphaNum|max:5' - 场景(如
add/edit)靠$scene数组控制:protected $scene = ['edit' => ['username', 'email']],调用时必须显式写$validate->scene('edit')->check($data),漏掉scene()就等于没设
自定义规则函数(如 checkPasswordStrength())必须是 protected 方法,参数顺序固定为 ($value, $rule, $data),返回 true 或错误字符串,不能返回 false 或 null。
控制器里怎么安全调用验证器
别用控制器基类的 $this->validate() ——它只是兼容层,绕过验证器类的所有扩展能力,TP6.0+ 已标记为“兼容性保留”:
- 推荐写法:
$validate = new \app\validate\User(); if (!$validate->check($data)) { return json(['code'=>400, 'msg'=>$validate->getError()]); } - 批量错误收集必须提前设:
$validate->batch(true),否则check()遇到第一个错就停,前端收不到全部提示 - 不要直接用
input('post.')做验证数据源,显式构造$data,避免意外传入is_admin等敏感字段被忽略却进数据库
真正麻烦的从来不是写规则,而是验证失败后怎么让前端拿到结构化错误信息、怎么确保敏感字段不被绕过、以及为什么加了 scene 却没生效——这些问题都藏在调用链的细节里,而不是验证器类本身。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











