TP8.0 验证器自定义规则编写全攻略【保姆级】

老辰小哥_6659

老辰小哥_6659

2026-07-09

927人浏览

原创

thinkphp 8.0 中自定义验证规则需通过 init() 方法或控制器动态注册,手机号校验需支持国际区号参数、身份证校验须预加载省份码避免实时查库,场景校验必须正确定义 $scene 属性否则规则失效。

tp8.0 验证器自定义规则编写全攻略【保姆级】

在 ThinkPHP 8.0 中为手机号加国际区号校验、为身份证号做末位校验、为密码强制要求含大小写字母和数字——这些不能靠内置规则解决的业务逻辑,必须写自定义验证规则,否则验证器直接报错或跳过校验。

注册自定义规则的两种入口

方法一:在验证器类的 init() 方法中注册(推荐)
打开 app/validate/UserValidate.php,在 init() 方法里调用 $this->extend(),传入别名和回调函数或方法名字符串。

方法二:在控制器中动态注册
创建验证器实例后,立即调用 $validate->extend(),适用于临时、一次性、不复用的规则,但无法被缓存复用,且无法参与场景(scene)校验。

【别名必须全局唯一】 若两个验证器都注册了 'id_card' 别名,后注册的会覆盖前一个,导致不可预期的校验行为。

写一个带参数的手机号校验规则

第一步:在 UserValidate 类的 init() 方法中注册闭包

$this->extend('isMobile', function($value, $rule) {
  $prefix = is_string($rule) ? $rule : ($rule[0] ?? '86');
  $pattern = match($prefix) {
    '86' => '/^1[3-9]\d{9}$/u',
    '852' => '/^([2-9]\d{7}|[2-9]\d{3}-\d{4})$/u',
    default => '/^\+' . preg_quote($prefix) . '\d{10,15}$/u';
  };
  return (bool) preg_match($pattern, $value);
});

第二步:在 $rule 中使用带参写法

'mobile' => 'isMobile:86' 或 'mobile' => 'isMobile:852',注意冒号后不要加空格。

第三步:在 $message 中配提示语

'mobile.isMobile' => ':attribute 必须是有效的 :rule 区号手机号',其中 :rule 会自动替换为传入的参数值(如 86)。

这一步操作起来很简单,直接把文件拖进去就行。但若漏掉 u 修饰符,中文或 emoji 输入时正则会匹配失败,且错误无提示,只返回 false。

写一个查库类的身份证校验规则

先在 __construct() 中预加载合法省份码,避免每次验证都查库:

$this->validProvinces = Cache::remember('idcard_provinces', 3600, function () {
  return Db::name('province_code')->column('code');
});

ThinkPHP5.1企业站点快速开发-源码课件
ThinkPHP5.1企业站点快速开发-源码课件

ThinkPHP5.1企业站点快速开发

下载

再定义校验方法,签名必须完整:

public function checkIdCard($value, $rule = '', $data = [], $field = '') {
  if (!is_string($value) || strlen($value) !== 18) {
    return '身份证长度必须为18位';
  }
  $provinceCode = substr($value, 0, 2) . '00';
  if (!in_array($provinceCode, $this->validProvinces)) {
    return '身份证归属地代码无效';
  }
  // 末位校验略(实际需补全)
  return true;
}

最后在 init() 中注册别名:

$this->extend('id_card', 'checkIdCard');

【禁止在回调里实时查库】 若此处直接写 Db::name('idcard_check')->where(...)->find(),高并发下数据库连接池会迅速耗尽,QPS 断崖式下跌。

验证器中启用场景并绑定规则

① 在验证器类中声明 $scene 属性,例如:

protected $scene = [
  'login' => ['username', 'password'],
  'register' => ['username', 'password', 'mobile', 'id_card'],
];

② 控制器中调用时指定场景名:

$result = $validate->scene('register')->check($data);

③ 场景字段可叠加额外规则:

protected $scene = [
  'register' => ['username', 'password', 'mobile', 'id_card'],
];
protected $pattern = [
  'username' => '/^[a-zA-Z][a-zA-Z0-9_]{4,19}$/u',
];

若未定义 $scene,调用 scene('xxx') 不会报错,但规则完全不生效,数据直接穿透过去——这个坑没有任何日志提示,只能靠断点确认。

相关文章

热门游戏推荐
热门游戏推荐

海量精品小游戏合集,无需安装即点即玩,休闲益智、动作闯关应有尽有,秒开即玩,轻松解压,快乐停不下来

下载

相关标签:

thinkphp

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

0

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

0

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

0

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

0

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

0

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

0

15

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

2026.10.22

0

15

PHP2Shell高危漏洞修复教程
PHP2Shell高危漏洞修复教程

PHP2Shell漏洞是什么,哪些PHP版本和运行环境会受到影响,服务器应该如何检测与修复?本专题提供版本自查脚本、Linux与Docker升级命令、PHP-FPM和Apache排查步骤,以及修复验证、临时缓解和应急响应方案。

2026.10.22

20

12

剧云人物设定与关系管理教程
剧云人物设定与关系管理教程

本专题介绍剧云人物设定与关系管理,讲解角色小传、性格职业、人物目标、背景资料和关系网络的创建及维护方法。

2026.10.22

0

16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程