hyperf 十五 验证器
官方文档:Hyperf
验证器报错需要配合多语言使用,创建配置自动生成对应的语言文件。
一 安装
composer require hyperf/validation:v2.2.33
composer require hyperf/translation:v2.2.33php bin/hyperf.php vendor:publish hyperf/translation
php bin/hyperf.php vendor:publish hyperf/validation
# config/autoload/middlewares.php 加中间件
return [// 下面的 http 字符串对应 config/autoload/server.php 内每个 server 的 name 属性对应的值,意味着对应的中间件配置仅应用在该 Server 中'http' => [// 数组内配置您的全局中间件,顺序根据该数组的顺序\Hyperf\Validation\Middleware\ValidationMiddleware::class],
];# /config/autoload/exception.php 加异常处理
return ['handler' => [// 这里对应您当前的 Server 名称'http' => [\Hyperf\Validation\ValidationExceptionHandler::class,],],
];
二 使用
#创建验证器
php bin/hyperf.php gen:request FooRequest
#设置验证规则 App\Request\FooRequest
public function rules(): array
{return ['foo' => 'required|max:255','bar' => 'required',];
}#设置验证规则 App\Controller\TestController
public function test9(FooRequest $request){// 传入的请求通过验证...// 获取通过验证的数据...$validated = $request->validated();var_dump($validated);}
比如请求http://127.0.0.1:9501/test/test9?foo=300,返回字符串"bar 字段是必须的"。foo规则max是判断字符长度,foo的用于比较的值是3,所以没报错。
三 规则
#用于文件校验
protected $fileRules = ['File', 'Image', 'Mimes', 'Mimetypes', 'Min','Max', 'Size', 'Between', 'Dimensions',
];#固有验证
protected $implicitRules = ['Required', 'Filled', 'RequiredWith', 'RequiredWithAll', 'RequiredWithout','RequiredWithoutAll', 'RequiredIf', 'RequiredUnless', 'Accepted', 'Present',
];
#依赖验证
protected $dependentRules = ['RequiredWith', 'RequiredWithAll', 'RequiredWithout', 'RequiredWithoutAll','RequiredIf', 'RequiredUnless', 'Confirmed', 'Same', 'Different', 'Unique','Before', 'After', 'BeforeOrEqual', 'AfterOrEqual', 'Gt', 'Lt', 'Gte', 'Lte',
];#size验证
protected $sizeRules = ['Size', 'Between', 'Min', 'Max', 'Gt', 'Lt', 'Gte', 'Lte'];#数字验证
protected $numericRules = ['Numeric', 'Integer'];
具体验证使用,查看官方教程。
四 自定义
1、自定义错误信息
#App\Request\FooRequest
public function messages(): array
{return ['foo.required' => 'foo is required','bar.required' => 'bar is required',];
}
2、自定义属性
#App\Request\FooRequest
public function attributes(): array
{return ['foo' => 'foo of request',];
}
3、自定义验证器
#App\Controller\TestTestController
public function test10(){$validator = $this->validationFactory->make($this->request->all(),['foo' => 'lt:10','bar' => 'required',],['foo.required' => 'foo is required','bar.required' => 'bar is required','lt' => ['numeric' => ':attribute 必须小于 [ :value ]'],'required' => ':attribute 字段是必须的~',]);if ($validator->fails()) {// Handle exception$errorMessage = $validator->errors()->all();var_dump($errorMessage);}var_dump("success");// Do something}#请求
http://127.0.0.1:9501/test/test10?foo=300#输出
array(2) {[0]=>string(27) "测试1 必须小于 [ 10 ]"[1]=>string(15) "bar is required"
}
string(7) "success"
测试证明 make第三个参数传入对应规则的报错信息,可以将原报错信息覆盖,但是和设置的对应属性的的对应规则的报错信息不兼容。
#修改自定义信息如下
[ 'required' => ':attribute 字段是必须的~','foo.required' => 'foo is required','bar.required' => 'bar is required','lt' => ['numeric' => ':attribute 必须小于 [ :value ]'],'required' => ':attribute 字段是必须的~',]#请求内容不变 报错信息
array(2) {[0]=>string(27) "测试1 必须小于 [ 10 ]"[1]=>string(15) "bar is required"
}
string(7) "success"
定义了属性的具体的报错信息,则采用属性的对应规则的报错信息。
4、自定义属性名
根据上述代码,在语言设置中如属性名。
#\storage\languages\zh_CN\validation.php
'attributes' => ['foo' => '测试1','bar' => '测试2',],#请求
http://127.0.0.1:9501/test/test10?foo=300#输出
array(2) {[0]=>string(23) "测试1 必须小于 10"[1]=>string(15) "bar is required"
}
string(7) "success"
根据测试证明 自定义中多语言字符串的设置,和其自带的不共用,需自己设置。
五 错误处理
错误返回信息使用类Hyperf\Utils\MessageBag。
MessageBag::add() 增加报错信息
MessageBag::has() 判断是否有某个属性报错
MessageBag::hasAny() 判断是否有某个属性报错
MessageBag::isEmpty() 判断是否为空
MessageBag::isNotEmpty() 、MessageBag::any() 判断是否不为空
MessageBag::first() 获取第一个报错
MessageBag::get() 获取某个属性的报错
MessageBag::all() 获取全部报错
MessageBag::unique();
MessageBag::messages()、MessageBag::getMessages()、MessageBag::toArray()、MessageBag::jsonSerialize() 返回错误信息数组,键值为属性名
还有些其他的,可以去看源码,使用方法可以看官方文档。
实际上$validator->errors()返回对象就是这个类。
六 详解
从使用 php bin/hyperf.php gen:request说起。
生成 Hyperf\Validation\Request\FormRequest\FormRequest子类,可以重写messages自定义消息、重写attributes自定义属性,必须设置rules方法定义验证规则,使用validated方法验证。使用验证返回的对象处理错误信息。其中错误信息以来于多语言模块。
验证流程:
FormRequest::validated()->FormRequest::getValidatorInstance()->FormRequest::createDefaultValidator()->Validator::validated()->Validator::invalid()->Validator::passes()->Validator::validateAttribute()->ValidatesAttributes::属性验证->FormatsMessages::makeReplacements()-> MessageBag::add(),最后返回可用的请求数据。
FormRequest::createDefaultValidator()获取默认验证器,传入通过容器获取的ValidatorFactory实体类,调用ValidatorFactory::make()->ValidatorFactory::resolve()流程,创建Validator对象并返回。
ValidatesAttributes类和FormatsMessages类都是trait类,通过在Validator类中使用use加载到类中。
源码如下
#模块配置内容 Hyperf\Validation\ConfigProvider'dependencies' => [PresenceVerifierInterface::class => DatabasePresenceVerifierFactory::class,FactoryInterface::class => ValidatorFactoryFactory::class,],
#Hyperf\Validation\Request\FormRequest
class FormRequest extends Request implements ValidatesWhenResolved
{public function validated(): array{return $this->getValidatorInstance()->validated();}public function messages(): array{return [];}public function attributes(): array{return [];}protected function getValidatorInstance(): ValidatorInterface{……if (method_exists($this, 'validator')) {$validator = call_user_func_array([$this, 'validator'], compact('factory'));} else {$validator = $this->createDefaultValidator($factory);}if (method_exists($this, 'withValidator')) {$this->withValidator($validator);}return $validator;});}protected function createDefaultValidator(ValidationFactory $factory): ValidatorInterface{return $factory->make($this->validationData(),$this->getRules(),$this->messages(),$this->attributes());}protected function getRules(){$rules = call_user_func_array([$this, 'rules'], []);$scene = $this->getScene();if ($scene && isset($this->scenes[$scene]) && is_array($this->scenes[$scene])) {$newRules = [];foreach ($this->scenes[$scene] as $field) {if (array_key_exists($field, $rules)) {$newRules[$field] = $rules[$field];}}return $newRules;}return $rules;}
}
#Hyperf\Validatio\ValidatorFactory
public function make(array $data, array $rules, array $messages = [], array $customAttributes = []): ValidatorInterface{$validator = $this->resolve($data,$rules,$messages,$customAttributes);……return $validator;}
protected function resolve(array $data, array $rules, array $messages, array $customAttributes): ValidatorInterface{if (is_null($this->resolver)) {return new Validator($this->translator, $data, $rules, $messages, $customAttributes);}return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes);}
#Hyperf\Validation\Validator
class Validator implements ValidatorContract
{use Concerns\FormatsMessages;use Concerns\ValidatesAttributes;public function after($callback): self{$this->after[] = function () use ($callback) {return call_user_func_array($callback, [$this]);};return $this;}public function validated(): array{if ($this->invalid()) {throw new ValidationException($this);}$results = [];$missingValue = Str::random(10);foreach (array_keys($this->getRules()) as $key) {$value = data_get($this->getData(), $key, $missingValue);if ($value !== $missingValue) {Arr::set($results, $key, $value);}}return $results;}public function invalid(): array{if (!$this->messages) {$this->passes();}return array_intersect_key($this->data,$this->attributesThatHaveMessages());}public function passes(): bool{$this->messages = new MessageBag();[$this->distinctValues, $this->failedRules] = [[], []];// We'll spin through each rule, validating the attributes attached to that// rule. Any error messages will be added to the containers with each of// the other error messages, returning true if we don't have messages.foreach ($this->rules as $attribute => $rules) {$attribute = str_replace('\.', '->', $attribute);foreach ($rules as $rule) {$this->validateAttribute($attribute, $rule);if ($this->shouldStopValidating($attribute)) {break;}}}// Here we will spin through all of the "after" hooks on this validator and// fire them off. This gives the callbacks a chance to perform all kinds// of other validation that needs to get wrapped up in this operation.foreach ($this->after as $after) {call_user_func($after);}return $this->messages->isEmpty();}protected function validateAttribute(string $attribute, $rule){……$method = "validate{$rule}";if ($validatable && !$this->{$method}($attribute, $value, $parameters, $this)) {$this->addFailure($attribute, $rule, $parameters);}}
}#假如判断lt
$method = "validateLt";#Hyperf\Validation\Concerns\ValidatesAttributespublic function validateLt(string $attribute, $value, array $parameters): bool{$this->requireParameterCount(1, $parameters, 'lt');$comparedToValue = $this->getValue($parameters[0]);$this->shouldBeNumeric($attribute, 'Lt');if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) {return $this->getSize($attribute, $value) < $parameters[0];}if (!$this->isSameType($value, $comparedToValue)) {return false;}return $this->getSize($attribute, $value) < $this->getSize($attribute, $comparedToValue);}
#Hyperf\Utils\MessageBag
class MessageBag implements Arrayable, Countable, Jsonable, JsonSerializable, MessageBagContract, MessageProvider
{public function __construct(array $messages = []){foreach ($messages as $key => $value) {$value = $value instanceof Arrayable ? $value->toArray() : (array) $value;$this->messages[$key] = array_unique($value);}}
}#其余比较多 可以查看源码
相关文章:
hyperf 十五 验证器
官方文档:Hyperf 验证器报错需要配合多语言使用,创建配置自动生成对应的语言文件。 一 安装 composer require hyperf/validation:v2.2.33 composer require hyperf/translation:v2.2.33php bin/hyperf.php vendor:publish hyperf/translation php bi…...
ssh访问远程宿主机的VMWare中NAT模式下的虚拟机
1.虚拟机端配置 1.1设置虚拟机的网络为NAT模式 1.2设置虚拟网络端口映射(NAT) 点击主菜单的编辑-虚拟网络编辑器: 启动如下对话框,选中NAT模式的菜单项,并点击NAT设置: 点击添加,为我们的虚拟机添加一个端口映射。…...
【一等奖方案】大规模金融图数据中异常风险行为模式挖掘赛题「NUFE」解题思路
第十届CCF大数据与计算智能大赛(2022 CCF BDCI)已圆满结束,大赛官方竞赛平台DataFountain(简称DF平台)正在陆续释出各赛题获奖队伍的方案思路,欢迎广大数据科学家交流讨论。 本方案为【大规模金融图数据中…...
npm install 报错
npm install 报错 npm install 报错 npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: yudao-ui-admin1.8.0-snapshot npm ERR! Found: eslint7.15.0 npm ERR! node_modules/eslint npm ERR! dev eslint&q…...
专业人士使用的3个好用的ChatGPT提示
AI正在席卷世界。从自动化各个领域的任务到几秒钟内协助我们的日常生活,它有着了公众还未理解的巨大价值……除非你是专业人士。 专业人士一般都使用什么提示以及如何使用的?这里是经验丰富的懂ChatGPT的专业人士才知道的3个提示。好用请复制收藏。 为…...
doris系列2: doris分析英国房产数据集
1.准备数据 2.doris建表 CREATE TABLE `uk_price_paid` (`id` varchar(50) NOT NULL,`price` int(20),`date` date...
精准运营,智能决策!解锁天翼物联水利水务感知云
面向智慧水利/水务数字化转型需求,天翼物联基于感知云平台创新能力,提供涵盖水利水务泛协议接入、感知云水利/水务平台、水利/水务感知数据治理、数据看板在内的水利水务感知云服务,构建水利水务感知神经系统新型数字化底座,实现智…...
CleanMyMac最新版4.14Mac清理软件下载安装使用教程
苹果电脑是很多人喜欢使用的一种电脑,它有着优美的外观,流畅的操作系统,丰富的应用程序和高效的性能。但是,随着时间的推移,苹果电脑也会产生一些不必要的文件和数据,这些文件和数据就是我们常说的垃圾。那…...
String.Format方法详解
在Java中,String.format() 方法可以用于将格式化的字符串写入输出字符串中。该方法将根据指定的格式字符串生成一个新的字符串,并使用可选的参数填充格式字符串中的占位符。以下是有关 String.format() 方法的更详细信息: 语法 public stati…...
【Mysql】关联查询1对多处理
关联查询1对多返回 遇见的问题 审批主表,和审批明细表,一张审批对应多张明细数据,每条明细数据的状态是不一样的,现在需要根据明细的状态获取到主单子的状态,状态返回矩阵如下 明细状态返回总状态都是已完成已完成都…...
vue 入门案例模版
vue 入门案例1 01.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> &l…...
el-select实现懒加载
先看一个线上的演示示例:https://code.juejin.cn/pen/7273352811440504889 背景 我们在实际开发中经常遇到这样的需求: el-select实现懒加载,用通俗的话说,为了增加响应速度,就是初始下拉只展示50条数据,…...
Java泛型机制
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏:每天一个知识点 ✨特色专栏:…...
Linux CentOS安装抓包解包工具Wireshark图形化界面
1.Wireshark介绍 Wireshark 是一个开源的网络协议分析工具,它能够捕获和分析网络数据包,提供深入的网络故障排除、网络性能优化和安全审计等功能。它支持跨多个操作系统,包括 Windows、macOS 和 Linux。 2.Wireshark主要使用方法 捕获数据…...
虹科分享 | 温度边缘效应对冻干成品含水量的影响(下)——优化和总结
上一篇文章中介绍到借助虹科Ellab的温度记录仪观察到由于冻干机壁面温度的影响,形成的边缘效应导致同一隔板的不同区域冻干饼块的干燥程度不均匀,含水量不同。 06 初次试验结果: 二次干燥中的产品温度显示: 放置在搁板中间的产品…...
ATF(TF-A)安全通告 TFV-1 (CVE-2016-10319)
安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-1 (CVE-2016-10319) 二、CVE-2016-10319 一、ATF(TF-A)安全通告 TFV-1 (CVE-2016-10319) Title 错误的固件更新SMC可能导致意外的大数据拷贝到安全内存中 CVE ID CVE-2016-10319 …...
说说我最近筛简历和面试的感受。。
大家好,我是鱼皮。 都说现在行情不好、找工作难,但招人又谈何容易?! 最近我们公司在招开发,实习社招都有。我收到的简历很多,但认真投递的、符合要求的却寥寥无几,而且都是我自己看简历、选人…...
Mysql /etc/my.cnf参数详解(一)
[mysqld] #server相关 server_id176452388 //每个MySQL服务器都需要具有唯一的server_id值 super_read_only 0 //不开启只读,在slave节点会开启即super_read_only 1 port 3306 //指定了Mysql开放的端口; default-storage-engine InnoDB skip-name…...
用最少数量的箭引爆气球【贪心算法】
用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地…...
Matlab论文插图绘制模板第109期—特征渲染的标签气泡散点图
在之前的文章中,分享了Matlab标签散点图的绘制模板: 特征渲染的标签散点图: 进一步,再来分享一下特征渲染的标签气泡散点图的绘制模板,从而可以再添加一个维度的信息。 先来看一下成品效果: 特别提示&…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...
