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);}}
}#其余比较多 可以查看源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/61613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React和Redux中的不变性

https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/ 一、不变性和副作用 1.不变&#xff1a;不断创造新值来替换旧值 2.不变性规则&#xff1a; &#xff08;1&#xff09;当给定相同的输入时&#xff0c;纯函数必须始终返回相同的值 &#xff08;2&#xff0…

如何利用Python代码优雅的进行文件下载

如何利用Python代码优雅的进行文件下载 一、什么是wget&#xff1f;二、使用wget.exe客户端进行文件下载三、使用Python脚本进行文件下载 欢迎学习交流&#xff01; 邮箱&#xff1a; z…1…6.com 网站&#xff1a; https://zephyrhours.github.io/ 一、什么是wget&#xff1f;…

JavaWeb_LeadNews_Day9-Redis实现用户行为

JavaWeb_LeadNews_Day9-Redis实现用户行为 网关配置点赞阅读不喜欢关注收藏文章详情-行为数据回显来源Gitee 网关配置 nacos: leadnews-app-gateway # 用户行为微服务 - id: leadnews-behavioruri: lb://leadnews-behaviorpredicates:- Path/behavior/**filters:- StripPrefi…

yolov3

yolov1 传统的算法 最主要的是先猜很多候选框&#xff0c;然后使用特征工程来提取特征&#xff08;特征向量&#xff09;,最后使用传统的机器学习工具进行训练。然而复杂的过程可能会导致引入大量的噪声&#xff0c;丢失很多信息。 从传统的可以总结出目标检测可以分为两个阶…

Java 读取TIFF JPEG GIF PNG PDF

Java 读取TIFF JPEG GIF PNG PDF 本文解决方法基于开源 tesseract 下载适合自己系统版本的tesseract &#xff0c;官网链接&#xff1a;https://digi.bib.uni-mannheim.de/tesseract/ 2. 下载之后安装&#xff0c;安装的时候选择选择语言包&#xff0c;我选择了中文和英文 3.…

提高Python并发性能 - asyncio/aiohttp介绍

在进行大规模数据采集时&#xff0c;如何提高Python爬虫的并发性能是一个关键问题。本文将向您介绍使用asyncio和aiohttp库实现异步网络请求的方法&#xff0c;并通过具体结果和结论展示它们对于优化爬虫效率所带来的效果。 1. 什么是异步编程&#xff1f; 异步编程是一种非阻…

vue使用打印组件print-js

项目场景&#xff1a; 由于甲方要求&#xff0c;项目需要打印二维码标签&#xff0c;故开发此功能 开发流程 安装包&#xff1a;npm install print-js --saveprint-js的使用 <template><div id"print" ref"print" ><p>打印内容<p&…

树的介绍(C语言版)

前言 在数据结构中树是一种很重要的数据结构&#xff0c;很多其他的数据结构和算法都是通过树衍生出来的&#xff0c;比如&#xff1a;堆&#xff0c;AVL树&#xff0c;红黑色等本质上都是一棵树&#xff0c;他们只是树的一种特殊结构&#xff0c;还有其他比如linux系统的文件系…

CocosCreator3.8研究笔记(二)windows环境 VS Code 编辑器的配置

一、设置文件显示和搜索过滤步骤 为了提高搜索效率以及文件列表中隐藏不需要显示的文件&#xff0c; VS Code 需要设置排除目录用于过滤。 比如 cocoscreator 中&#xff0c;编辑器运行时会自动生成一些目录&#xff1a;build、temp、library&#xff0c; 所以应该在搜索中排除…

代码随想录算法训练营第五十一天 | 309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费

代码随想录算法训练营第五十一天 | 309.最佳买卖股票时机含冷冻期&#xff0c;714.买卖股票的最佳时机含手续费 309.最佳买卖股票时机含冷冻期714.买卖股票的最佳时机含手续费 309.最佳买卖股票时机含冷冻期 题目链接 视频讲解 给定一个整数数组prices&#xff0c;其中第 pric…

Mysql-索引查询相关

一、单表查询 1.1 二级索引为null 不论是普通的二级索引&#xff0c;还是唯一二级索引&#xff0c;它们的索引列对包含 NULL 值的数量并不限制&#xff0c;所以我们采用key IS NULL 这种形式的搜索条件最多只能使用 ref 的访问方法&#xff0c;而不是 const 的访问方法 1.2 c…

深入探索PHP编程:连接数据库的完整指南

深入探索PHP编程&#xff1a;连接数据库的完整指南 在现代Web开发中&#xff0c;与数据库进行交互是不可或缺的一部分。PHP作为一种强大的服务器端编程语言&#xff0c;提供了丰富的工具来连接和操作各种数据库系统。本篇教程将带您了解如何在PHP中连接数据库&#xff0c;执行…

并发编程的故事——并发之共享模型

并发之共享模型 文章目录 并发之共享模型一、多线程带来的共享问题二、解决方案三、方法中的synchronize四、变量的线程安全分析五、习题六、Monitor七、synchronize优化八、wait和notify九、sleep和wait十、park和unpark十一、重新理解线程状态十二、多把锁十三、ReentrantLoc…

Window11-Ubuntu双系统安装

一、制作Ubuntu系统盘 1.下载Ubuntu镜像源 阿里云开源镜像站&#xff1a;https://mirrors.aliyun.com/ubuntu-releases/ 清华大学开源软件镜像网站&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/ 选择想要的版本下载&#xff0c;我用的是20.04版本。 2…

关于类和接口

类和接口的区别&#xff0c;去除语法层面&#xff0c;谈谈编程层面的意义。 设计原则SOLID&#xff1a; S&#xff1a;单一职责(SRP)&#xff0c;Single Responsibility Principle O&#xff1a;开-闭原则(OCP)&#xff0c;Open-Closed Principle L&#xff1a;里氏替换(LSP)&…

Facebook登录SDK

一、Facebook SDK接入 官方文档&#xff1a;https://developers.facebook.com/docs/facebook-login/android 按照流程填写完成 1、选择新建应用 如果已经创建了应用就点【搜索你的应用】&#xff0c;忽略2、3步骤 2、选择【允许用户用自己的Facebook账户登录】 3、填写应用…

Qt应用开发(基础篇)——消息对话框 QMessageBox

一、前言 QMessageBox类继承于QDialog&#xff0c;是一个模式对话框&#xff0c;常用于通知用户或向用户提出问题并接收答案。 对话框QDialog QMessageBox消息框主要由四部分组成&#xff0c;一个主要文本text&#xff0c;用于提醒用户注意某种情况;一个信息文本informativeTex…

Redis数据结构应用场景及原理分析

目录 一、Redis介绍 二、应用场景 2.1 String应用场景 2.2 Hash应用场景 2.3 List应用场景 2.4 Set应用场景 2.5 Zset应用场景 一、Redis介绍 单线程多路复用底层数据结构&#xff1a;全局哈希表&#xff08;key-value&#xff09; 二、应用场景 2.1 String应用…

VBA技术资料MF50:VBA_在Excel中突出显示前3个值

【分享成果&#xff0c;随喜正能量】人受到尊重&#xff0c;不是因为权钱&#xff0c;而是他骨子里透出的&#xff0c;正直与善良。。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高…

ChatGPT 总结数据分析的所有知识点

ChatGPT功能非常多,特别是对某个行业,某个方向,某个技术进行总结那是相当专业的。 如下图。 直接用一个指令便总结出来数据分析当中的所有知识点内容。 AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle, Office, Python ,ETL Ex…