ThinkPHP场景动态验证
一、缘由
今天在用thinkphp8写东西的时候发现,写验证器规则和场景优点费时间,就算用tinkphp的命令行生成也是生成一个空壳。内容还是要自己填写感觉麻烦。
就突发奇想能不能自动生成验证器,也不能是说自动生成验证器,生成验证其的话还是要生成相关的文件,这块因为没弄过就略过
就是说能写一个公共的动态验证器 然后规则场景啥的手动输入表名,场景规则和需要使用的场景。经过我小半天的尝试,初见成效,话不多说 上代码
二、实现
实现步骤
1、创建正常的验证器的模式
包含rule(规则) message(提示信息) scene(场景)
代码示例
<?phpnamespace app\services;
use think\Validate;
class AdminValidatee extends Validate
{/*** 定义验证规则* 格式:'字段名' => ['规则1','规则2'...]** @var array*/protected $rule = [];/*** 定义错误信息* 格式:'字段名.规则名' => '错误信息'** @var array*/protected $message = [];
}
2、添加验证场景
代码示例
namespace app\services;
use think\Validate;
class AdminValidatee extends Validate
{/*** 定义验证规则* 格式:'字段名' => ['规则1','规则2'...]** @var array*/protected $rule = [];/*** 定义错误信息* 格式:'字段名.规则名' => '错误信息'** @var array*/protected $message = [];/*** 定义验证场景* 格式:'场景名' => ["字段1","字段2"]** @var array*/protected $scene= [];
}
3、创建一个获取表结构的方法
用户动态获取表的结构,包括字段,字段类型
代码示例:
// 获取表结构信息$sql="SELECT COLUMN_NAME ,COLUMN_TYPE ,IS_NULLABLE ,COLUMN_DEFAULT ,COLUMN_COMMENT FROM information_schema.COLUMNSWHERE TABLE_SCHEMA = '$databaseName' AND TABLE_NAME ='$tableName'";// 获取表结构信息$columns = Db::query($sql);$rules = [];$messages = [];foreach ($columns as $column) {$field = $column['COLUMN_NAME'];//字段名$fieldName = $column['COLUMN_COMMENT'];//注释$type = $column['COLUMN_TYPE'];//字段类型$isNullable = $column['IS_NULLABLE'] === 'YES' ? true : false;//是不是为null// 根据字段类型和表结构自动生成验证规则$rule = 'require';// 如果字段允许为空,则移除 'require' 规则if ($isNullable) {$rule = 'nullable';}if (strpos($type, 'varchar') !== false || strpos($type, 'text') !== false) {$rule .= '|length:1,255'; // 字符串类型添加长度验证}if (strpos($type, 'int') !== false) {$rule .= '|number'; // 整数类型字段添加数字验证}// 针对 email 字段,增加邮箱格式验证if ($field == 'email') {$rule .= '|email';}// 添加到验证规则数组$rules[$field] = $rule;$messages[$field] = ucfirst($fieldName.$field) . ' is required and should be of valid format';}return ['rules' => $rules, 'messages' => $messages];
4、创建验证方法
/*** 验证* User: MirGao* Date: 2024/12/3* Time: 14:58* @param $param* @param $scene* @return void*/public function validate($param,$scene){if(!self::scene($scene)->check($param)){exit(json_encode(['code'=>'203','message'=>Validate::getError(),'data'=>[]]));}}
5、接收实例化传过来的参数用构造函数进行赋值
//参数为表名和验证场景public function __construct($table,$sceneRule){parent::__construct();//通过表名动态获取表结构$data=self::getValidate($table);//赋值规则$this->rule=$data['rules'];//赋值提示信息$this->message=$data['messages'];//赋值验证场景$this->scene=$sceneRule;}
6、完整代码
<?php
/*** Notes:* User: 14736* Date: 2024/12/3* Time: 13:46* @return*/namespace app\services;use think\facade\Db;
use think\Validate;class ValidateService extends Validate
{protected $rule = [];protected $message = [];protected $scene = [];//参数为表名和验证场景public function __construct($table,$sceneRule){parent::__construct();//通过表名动态获取表结构$data=self::getValidate($table);//赋值规则$this->rule=$data['rules'];//赋值提示信息$this->message=$data['messages'];//赋值验证场景$this->scene=$sceneRule;}/*** 获取表结构数据* User: MirGao* Date: 2024/12/3* Time: 14:58* @param $tableName 表名* @return array[]*/static public function getValidate($tableName){// 获取表结构信息$sql="SELECT COLUMN_NAME ,COLUMN_TYPE ,IS_NULLABLE ,COLUMN_DEFAULT ,COLUMN_COMMENT FROM information_schema.COLUMNSWHERE TABLE_SCHEMA = 'questions' AND TABLE_NAME ='$tableName'";// 获取表结构信息$columns = Db::query($sql);$rules = [];$messages = [];foreach ($columns as $column) {$field = $column['COLUMN_NAME'];$fieldName = $column['COLUMN_COMMENT'];$type = $column['COLUMN_TYPE'];$isNullable = $column['IS_NULLABLE'] === 'YES' ? true : false;// 根据字段类型和表结构自动生成验证规则$rule = 'require';// 如果字段允许为空,则移除 'require' 规则if ($isNullable) {$rule = 'nullable';}if (strpos($type, 'varchar') !== false || strpos($type, 'text') !== false) {$rule .= '|length:1,255'; // 字符串类型添加长度验证}if (strpos($type, 'int') !== false) {$rule .= '|number'; // 整数类型字段添加数字验证}// 针对 email 字段,增加邮箱格式验证if ($field == 'email') {$rule .= '|email';}// 添加到验证规则数组$rules[$field] = $rule;$messages[$field] = ucfirst($fieldName.$field) . ' is required and should be of valid format';}return ['rules' => $rules, 'messages' => $messages];}/*** 验证* User: MirGao* Date: 2024/12/3* Time: 14:58* @param $param* @param $scene* @return void*/public function validate($param,$scene){if(!self::scene($scene)->check($param)){exit(json_encode(['code'=>'203','message'=>Validate::getError(),'data'=>[]]));}}
}
三、调用
客户端示例
<?php
/*** Notes:* User: 14736* Date: 2024/12/3* Time: 13:17* @return*/namespace app\admin\controller;use app\admin\model\AdminModel;
use app\admin\validate\AdminValidate;
use app\services\JsonResponse;
use app\services\JwtService;
use app\services\ValidateService;
use think\Request;class LoginController
{//定义验证场景protected $sceneRule=[];public function __construct(){//根据业务进行添加场景$this->sceneRule=['login'=>['admin_account','admin_password']];}/*** 登录* User: MirGao* Date: 2024/12/3* Time: 15:04* @param Request $request* @param JwtService $jwtService* @param AdminModel $adminModel* @return \think\response\Json*/public function login(Request $request ,JwtService $jwtService,AdminModel $adminModel){$param=$request->post();//传入表名 验证场景$validate=new ValidateService('system_admin',$this->sceneRule);$validate->validate($param,'login');$adminId='查询语句';if(empty($adminId)){return JsonResponse::error('用户不存在');}$token= $jwtService->getToken($adminId);return JsonResponse::successData(['token'=>$token]);}}
接口调用示例
四、总结
优点
1、写起来简便,完成一个公共验证文件后只需要传入 表明和验证场景并调用验证场景中的相关规则即可完成验证
2、无需关心表的结构变化
缺点
1、每次调用都会去查询数据库性能开销有点大
2、耦合性很高 所有的验证都走这一个方法调试时会比较差异化
3、要求开发者建表时要按照规范,写字段注释
优化
针对于每次验证都需要查询表结构,建议上缓存,查询后把表结构放在缓存里,当表结构发生变化时需要及时更新缓存,如果有更好的想法欢迎交流
相关文章:

ThinkPHP场景动态验证
一、缘由 今天在用thinkphp8写东西的时候发现,写验证器规则和场景优点费时间,就算用tinkphp的命令行生成也是生成一个空壳。内容还是要自己填写感觉麻烦。 就突发奇想能不能自动生成验证器,也不能是说自动生成验证器,生成验证其的…...

在M3上面搭建一套lnmp环境
下载docker-desktop 官网下载docker-desktop 切换镜像源 {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["https://docke…...

【C++笔记】二叉搜索树
前言 各位读者朋友们大家好!上期我们讲完了面向对象编程三大属性之一的多态,这一期我们再次开始数据结构二叉搜索树的讲解。 目录 前言一. 二叉搜索树的概念二. 二叉搜索树的性能分析三. 二叉搜索树的插入四. 二叉搜索树的查找五. 二叉搜索树的删除六.…...
Fork/Join框架简介
一、Fork/Join框架简介 Fork/Join框架是Java 7引入的一个用于并行执行任务的框架,它可以将一个大任务分割成若干个小任务,并行执行这些小任务,然后将每个小任务的结果合并起来,得到大任务的结果。这种框架特别适合于能够被递归分…...

Java项目实战II基于微信小程序的电子竞技信息交流平台的设计与实现(开发文档+数据库+源码)
目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着互联网技术的飞速发展…...

Mysql读写分离分库分表
读写分离 什么是读写分离 读写分离主要是为了将对数据库的读写操作分散到不同的数据库节点上。 这样的话,就能够小幅提升写性能,大幅提升读性能。一般情况下,我们都会选择一主多从,也就是一台主数据库负责写,其他的从…...

B站狂神说--springboot项目学习(新建一个springboot项目)
文章目录 1.新建项目java8项目1.解决自带的idea2024无法使用java8的问题 2.新建接口3.项目打包为jar包4.使用jar包 1.新建项目java8项目 1.解决自带的idea2024无法使用java8的问题 将server.url修改为阿里云的地址:https://start.aliyun.com/ 选择Spring Web 创建…...

eltable el-table 横向 滚动条常显
又遇到了难受的问题,el-table嵌入在一个div里面,结果因为内容太多,横向、纵向我都得滚动查看! 结果发现横向滚动时只能让它纵向触底后才能进行横向操作,这就很变态,明显不符合用户操作习惯。如下图: 要先纵…...

centos8 mysql 主从复制
原理 一、一主一从 准备工作 1.主库配置 1、修改配置文件 /etc/my.cnf #mysql 服务ID,保证整个集群环境中唯一,取值范围:1-232-1,默认为 server-id1 #是否只读,1 代表只读,0代表读写 read-only0 #忽略的数据,指不需要同步的数据库 #binlog…...

【C++】入门【五】
本节目标 一、C/C内存分布 二、C语言中动态内存管理方式 三、C中动态内存管理 四、operator new与operator delete函数 五、new和delete的实现原理 六、定位new表达式(placement-new) 七、常见面试题 一、C/C内存分布 一个程序占用的内存主要有以下几部分栈区(stac…...

【React】二、状态变量useState
文章目录 1、React中的事件绑定1.1 基础事件绑定1.2 使用事件对象参数1.3 传递自定义参数1.4 同时传递事件对象和自定义参数 2、React中的组件3、useState 1、React中的事件绑定 1.1 基础事件绑定 语法:on 事件名称 { 事件处理程序 },整体上遵循驼峰…...
SQL Server中的数据处理函数:提升SQL查询能力
文章目录 前言1. 数据类型转换函数CAST()CONVERT()TRY_CAST() 和 TRY_CONVERT() 2. 数学函数ABS()CEILING()FLOOR()ROUND()POWER()SQRT() 3. 日期和时间函数GETDATE()SYSDATETIME()DATEADD()DATEDIFF()YEAR()、MONTH() 和 DAY()FORMAT() 4. 条件处理函数CASEIIF() 总结 前言 在…...
TypeScript 语言学习入门级教程五
在前面的教程中,我们已经逐步深入地学习了 TypeScript 的诸多特性,包括基础语法、类型系统、面向对象编程、装饰器以及一些高级类型等。在本教程中,我们将聚焦于 TypeScript 的模块系统、命名空间与模块的关系、声明文件以及如何在实际项目中…...
上海市计算机学会竞赛平台2022年7月月赛丙组匹配括号(三)
题目描述 如果字符序列仅由 ( 与 ) 构成,则在满足以下条件时,它是匹配的: 空序列是匹配的;如果括号序列 s 是匹配的,那么 (s) 也是匹配的;如果括号序列 s 与 t 是匹配的,那么 st 也是匹配的。…...

108.【C语言】数据结构之二叉树查找值为x的节点
目录 1.题目 代码模板 2.分析 分类讨论各种情况 大概的框架 关键部分(继续递归)的详解 递归调用展开图 3.测试结果 其他写法 4.结论 5.注意事项 不推荐的写法 1.题目 查找值为x的节点并返回节点的地址 代码模板 typedef int BTDataType; typedef struct BinaryT…...

Java学习笔记(10)--面向对象基础
学习资料来自黑马程序员 目录 设计对象并使用 类和对象 定义类 创建类的对象 使用对象 类的几个补充注意事项 设计对象并使用 类和对象 类(设计图):是对象共同特征的描述。 对象:是真实存在的具体东西。 在Java中必须先…...

社群分享在商业引流与职业转型中的作用:开源 AI 智能名片 2+1 链动模式小程序的应用契机
摘要:本文聚焦于社群分享在商业领域的重要性,阐述其作为干货诱饵在引流方面的关键意义。详细探讨了提供有价值干货的多种方式,包括文字分享、问题解答以及直播分享等,并分析了直播分享所需的条件。同时,以自身经历为例…...
nodejs官方文档学习-笔记-1
一、异步工作 process.nextTick(): 回调会在当前操作完成后立即执行,但在事件循环进入下一个阶段之前。它是最先执行的。 Promise.then(): 回调会在 microtask 队列中执行,通常是在当前操作完成后,但在事件循环进入…...
android视频播放器之DKVideoPlayer
一个老牌子的播放器了,项目可能已经有些日子没有维护了。但是使用效果还是不错的。支持多种视频格式,及重力感应、调节亮度等多种效果。想来想去,还是记录下来,我会在文章的最后注明github地址: 首先引入依赖ÿ…...

Linux——基础命令(3)
1.Linux——基础命令(1)-CSDN博客 2.Linux——基础命令(2) 文件内容操作-CSDN博客 一、打包压缩 打包压缩 是日常工作中备份文件的一种方式 在不同操作系统中,常用的打包压缩方式是不同的选项 含义 Windows 常用 rar…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...