当前位置: 首页 > 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; 特别提示&…...

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

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

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...