当前位置: 首页 > news >正文

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 十五 验证器

官方文档&#xff1a;Hyperf 验证器报错需要配合多语言使用&#xff0c;创建配置自动生成对应的语言文件。 一 安装 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) 点击主菜单的编辑-虚拟网络编辑器&#xff1a; 启动如下对话框&#xff0c;选中NAT模式的菜单项&#xff0c;并点击NAT设置&#xff1a; 点击添加&#xff0c;为我们的虚拟机添加一个端口映射。…...

【一等奖方案】大规模金融图数据中异常风险行为模式挖掘赛题「NUFE」解题思路

第十届CCF大数据与计算智能大赛&#xff08;2022 CCF BDCI&#xff09;已圆满结束&#xff0c;大赛官方竞赛平台DataFountain&#xff08;简称DF平台&#xff09;正在陆续释出各赛题获奖队伍的方案思路&#xff0c;欢迎广大数据科学家交流讨论。 本方案为【大规模金融图数据中…...

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正在席卷世界。从自动化各个领域的任务到几秒钟内协助我们的日常生活&#xff0c;它有着了公众还未理解的巨大价值……除非你是专业人士。 专业人士一般都使用什么提示以及如何使用的&#xff1f;这里是经验丰富的懂ChatGPT的专业人士才知道的3个提示。好用请复制收藏。 为…...

doris系列2: doris分析英国房产数据集

1.准备数据 2.doris建表 CREATE TABLE `uk_price_paid` (`id` varchar(50) NOT NULL,`price` int(20),`date` date...

精准运营,智能决策!解锁天翼物联水利水务感知云

面向智慧水利/水务数字化转型需求&#xff0c;天翼物联基于感知云平台创新能力&#xff0c;提供涵盖水利水务泛协议接入、感知云水利/水务平台、水利/水务感知数据治理、数据看板在内的水利水务感知云服务&#xff0c;构建水利水务感知神经系统新型数字化底座&#xff0c;实现智…...

CleanMyMac最新版4.14Mac清理软件下载安装使用教程

苹果电脑是很多人喜欢使用的一种电脑&#xff0c;它有着优美的外观&#xff0c;流畅的操作系统&#xff0c;丰富的应用程序和高效的性能。但是&#xff0c;随着时间的推移&#xff0c;苹果电脑也会产生一些不必要的文件和数据&#xff0c;这些文件和数据就是我们常说的垃圾。那…...

String.Format方法详解

在Java中&#xff0c;String.format() 方法可以用于将格式化的字符串写入输出字符串中。该方法将根据指定的格式字符串生成一个新的字符串&#xff0c;并使用可选的参数填充格式字符串中的占位符。以下是有关 String.format() 方法的更详细信息&#xff1a; 语法 public stati…...

【Mysql】关联查询1对多处理

关联查询1对多返回 遇见的问题 审批主表&#xff0c;和审批明细表&#xff0c;一张审批对应多张明细数据&#xff0c;每条明细数据的状态是不一样的&#xff0c;现在需要根据明细的状态获取到主单子的状态&#xff0c;状态返回矩阵如下 明细状态返回总状态都是已完成已完成都…...

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实现懒加载

先看一个线上的演示示例&#xff1a;https://code.juejin.cn/pen/7273352811440504889 背景 我们在实际开发中经常遇到这样的需求&#xff1a; el-select实现懒加载&#xff0c;用通俗的话说&#xff0c;为了增加响应速度&#xff0c;就是初始下拉只展示50条数据&#xff0c…...

Java泛型机制

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…...

Linux CentOS安装抓包解包工具Wireshark图形化界面

1.Wireshark介绍 Wireshark 是一个开源的网络协议分析工具&#xff0c;它能够捕获和分析网络数据包&#xff0c;提供深入的网络故障排除、网络性能优化和安全审计等功能。它支持跨多个操作系统&#xff0c;包括 Windows、macOS 和 Linux。 2.Wireshark主要使用方法 捕获数据…...

虹科分享 | 温度边缘效应对冻干成品含水量的影响(下)——优化和总结

上一篇文章中介绍到借助虹科Ellab的温度记录仪观察到由于冻干机壁面温度的影响&#xff0c;形成的边缘效应导致同一隔板的不同区域冻干饼块的干燥程度不均匀&#xff0c;含水量不同。 06 初次试验结果&#xff1a; 二次干燥中的产品温度显示&#xff1a; 放置在搁板中间的产品…...

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 …...

说说我最近筛简历和面试的感受。。

大家好&#xff0c;我是鱼皮。 都说现在行情不好、找工作难&#xff0c;但招人又谈何容易&#xff1f;&#xff01; 最近我们公司在招开发&#xff0c;实习社招都有。我收到的简历很多&#xff0c;但认真投递的、符合要求的却寥寥无几&#xff0c;而且都是我自己看简历、选人…...

Mysql /etc/my.cnf参数详解(一)

[mysqld] #server相关 server_id176452388 //每个MySQL服务器都需要具有唯一的server_id值 super_read_only 0 //不开启只读&#xff0c;在slave节点会开启即super_read_only 1 port 3306 //指定了Mysql开放的端口&#xff1b; default-storage-engine InnoDB skip-name…...

用最少数量的箭引爆气球【贪心算法】

用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地…...

Matlab论文插图绘制模板第109期—特征渲染的标签气泡散点图

在之前的文章中&#xff0c;分享了Matlab标签散点图的绘制模板&#xff1a; 特征渲染的标签散点图&#xff1a; 进一步&#xff0c;再来分享一下特征渲染的标签气泡散点图的绘制模板&#xff0c;从而可以再添加一个维度的信息。 先来看一下成品效果&#xff1a; 特别提示&…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...