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…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
