Respect/Validation 中的 Uuid 校验器:从基础用法到源码级原理解析
发布时间:2026/10/10 6:08:26 锦皓数字建站

后端开发工具【免费下载链接】ValidationThe most awesome validation engine ever created for PHP项目地址https://gitcode.com/gh_mirrors/va/Validation点击查看免费下载本篇技术指南以 Respect/Validation 仓库中的 Uuid 校验器文档 为骨架系统讲解v::uuid()的构造签名、版本限定v1v8、模板消息定制并结合 src/Validators/Uuid.php 源码与 单元测试、特性测试 深入剖析其底层实现。读完本文你将掌握如何在 PHP 8.5 项目中正确使用、定制并理解 UUID 校验规则包括如何应对ramsey/uuid依赖缺失、非法版本参数以及非字符串输入等边界场景。一、规则概述与构造签名Uuid校验器用于判断输入是否为合法的 UUIDUniversally Unique Identifier并且可选地限定其版本为 1 至 8。该规则在 validators.md 中被归类为Strings字符串类别。文档中给出的三种构造签名如下Uuid()Uuid(int $version)Uuid(int $version, UuidFactory $uuidFactory)对应源码 src/Validators/Uuid.php 的构造函数public function __construct( private readonly int|null $version null, UuidFactory|null $uuidFactory null, )$version期望校验的 UUID 版本null表示不限定版本只要解析出是 UUID 即通过$uuidFactory解析器工厂默认使用new UuidFactory()。1.1 依赖说明ramsey/uuid该规则基于ramsey/uuid库实现。在 composer.json 中ramsey/uuid: ^4位于require-dev中在suggest中注明ramsey/uuid: Enables the UUID rule if available。也就是说运行官方测试套件需要安装该依赖生产环境使用Uuid规则时你需要自行执行composer require ramsey/uuid。源码构造函数中做了显式防护src/Validators/Uuid.phpif ($uuidFactory null !class_exists(UuidFactory::class)) { throw new MissingComposerDependencyException( Uuid rule requires ramsey/uuid package, ramsey/uuid, ); }如果未安装依赖就实例化规则会抛出MissingComposerDependencyException并提示所需的包名ramsey/uuid。1.2 版本参数校验若显式传入$version构造函数会先调用isSupportedVersion()校验范围src/Validators/Uuid.phpprivate function isSupportedVersion(int $version): bool { return $version 1 $version 8; }版本不在 18 之间时抛出InvalidValidatorException消息为Only versions 1 to 8 are supported: %d given。这一点被 单元测试 明确覆盖self::expectException(InvalidValidatorException::class); self::expectExceptionMessage(Only versions 1 to 8 are supported: . $version . given); new Uuid($version);二、基本用法与代码示例文档中给出了最核心的实操示例此处完整保留并补充说明// 不限定版本任何合法 UUIDv1~v8均通过 v::uuid()-assert(eb3115e5-bd16-4939-ab12-2b95745a30f3); // Validation passes successfully // 非 UUID 字符串 → 校验失败 v::uuid()-assert(Hello World!); // → Hello World! must be a UUID // 不带连字符的紧凑格式同样合法 v::uuid()-assert(eb3115e5bd164939ab122b95745a30f3); // Validation passes successfully // 限定 v1 v::uuid(1)-assert(eb3115e5-bd16-4939-ab12-2b95745a30f3); // → eb3115e5-bd16-4939-ab12-2b95745a30f3 must be a UUID v1 // 限定 v4 v::uuid(4)-assert(eb3115e5-bd16-4939-ab12-2b95745a30f3); // Validation passes successfully // 限定 v8 v::uuid(8)-assert(00112233-4455-8677-8899-aabbccddeeff); // Validation passes successfully // 接受 Ramsey\Uuid\UuidInterface 对象作为输入 v::uuid(4)-assert(\Ramsey\Uuid\Uuid::fromString(eb3115e5-bd16-4939-ab12-2b95745a30f3)); // Validation passes successfully2.1 支持的输入类型从源码 src/Validators/Uuid.php 可以看到规则接受两类输入if (!is_string($input) !($input instanceof UuidInterface)) { return Result::failed($input, $this, $parameters, $template); }字符串标准 8-4-4-4-12 带连字符格式或去掉连字符的紧凑格式32 位十六进制Ramsey\Uuid\UuidInterface对象即\Ramsey\Uuid\Uuid::fromString()等工厂方法产出的对象。其余类型数组、布尔值、普通对象、空字符串等会直接判定失败。这一行为由 单元测试 中的providerForInvalidInput验证包括、[]、true、false、new stdClass()等场景。2.2 非法 UUID 的判定值得注意的是nil UUID全零00000000-0000-0000-0000-000000000000也被视为非法。测试数据中还包含一个典型反例g71a18f4-3a13-11e7-a919-92ebcb67fe33包含g这一非十六进制字符说明解析失败即校验失败。三、源码级原理evaluate() 的执行流程Uuid实现了Validator接口核心逻辑在evaluate()方法中src/Validators/Uuid.php整体流程如下选择模板若指定了版本使用TEMPLATE_VERSION__version__否则使用TEMPLATE_STANDARD并携带[version $this-version]参数类型检查非字符串且非UuidInterface实例直接返回失败结果解析字符串交给$this-uuidFactory-fromString($input)解析对象则直接使用解析抛出的任何Throwable都被捕获并转为失败结果提取版本通过$uuid-getFields()-getVersion()取得 UUID 的版本号v1~v8判定指定版本时$uuidVersion $this-version未指定版本时$uuidVersion ! null即只要是合法 UUID 就通过。这里体现了无版本参数 任意版本皆可的设计未指定版本时只要getVersion()有值即通过。单元测试用ALL_VERSIONS常量覆盖了 v1v8 全部样例字符串、紧凑格式字符串与RamseyUuid::fromString()对象三种输入形态tests/unit/Validators/UuidTest.php并交叉验证了期望版本与输入版本不一致时失败的全部组合。此外ContainerRegistry.php 中已将UuidFactory::class注册进默认容器UuidFactory::class new Instantiator(UuidFactory::class)因此在默认装配下规则会自动获得解析工厂无需手工注入。四、错误消息模板与占位符规则通过 PHP 8 属性#[Template]声明消息模板可同时作为属性Attribute用于属性级校验类声明为#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]。4.1Uuid::TEMPLATE_STANDARD模式模板default{{subject}} must be a UUIDinverted{{subject}} must not be a UUID4.2Uuid::TEMPLATE_VERSION模式模板default{{subject}} must be a UUID v{{version\|raw}}inverted{{subject}} must not be a UUID v{{version\|raw}}4.3 占位符说明占位符说明subject被校验的输入值或自定义的校验器名称若指定version期望的 UUID 版本号模板中的{{version|raw}}使用了占位符管道修饰符Placeholder Piperaw修饰符可去掉默认的引号包裹详见 placeholder-pipes.md从而在错误消息中呈现v1、v4这类不带引号的版本号。4.4 消息渲染示例特性测试 精确断言了消息内容例如v::uuid()-assert(g71a18f4-3a13-11e7-a919-92ebcb67fe33); // → g71a18f4-3a13-11e7-a919-92ebcb67fe33 must be a UUID v::uuid(1)-assert(e0b5ffb9-9caf-2a34-9673-8fc91db78be6); // → e0b5ffb9-9caf-2a34-9673-8fc91db78be6 must be a UUID v1 v::not(v::uuid())-assert(fb3a7909-8034-59f5-8f38-21adbc168db7); // → fb3a7909-8034-59f5-8f38-21adbc168db7 must not be a UUIDinverted模板由v::not()包装时自动启用assert()抛出的异常消息可直接用于面向用户或日志的错误展示。五、组合用法与进阶场景Uuid规则可无缝嵌入 Respect/Validation 的链式与批量 API取反v::not(v::uuid())校验不是合法 UUID数组批量校验v::allUuid()、v::allUuid($version)见 src/Mixins/AllBuilder.php逐项校验数组中的每个元素键值校验v::keyUuid(user_id, 4)见 src/Mixins/KeyBuilder.php对关联数组指定键做 v4 UUID 校验属性级校验借助#[Attribute]特性可直接把规则注解到 DTO 属性上。版本限定在实际业务中的典型价值在于例如用户 ID 必须为 v4 随机 UUID或订单号必须为 v7 时间序 UUID通过v::uuid(4)/v::uuid(7)即可把格式与语义一并约束。六、变更历史与相关规则文档 Changelog 记载了该规则的演进版本说明3.0.0消息模板调整Templates changed3.0.0开始依赖ramsey/uuid2.0.0规则创建在 v3 中规则重构为基于Result对象的evaluate()结构且模板机制与占位符管道全面升级。同属字符串校验的相关规则可参照 Base、Decimal 与 Digit例如v::base(16)校验十六进制数字串、v::digit()校验纯数字与v::uuid()一样都属于格式类字符串规则可根据业务粒度组合选用。七、总结Uuid校验器是一个小而精的规则通过可选的版本参数覆盖 v1v8 全谱系校验接受字符串与UuidInterface对象两种输入兼容带连字符与紧凑格式并以MissingComposerDependencyException/InvalidValidatorException两类异常对依赖缺失和非法参数做出明确反馈。无论是日常表单校验、API 参数过滤还是 DTO 属性注解校验v::uuid()都提供了开箱即用且可定制错误消息的解决方案。赞分享后端开发工具【免费下载链接】ValidationThe most awesome validation engine ever created for PHP项目地址https://gitcode.com/gh_mirrors/va/Validation点击查看免费下载相关推荐Respect Validation 长度校验器 Length 深入解析从基础用法到源码原理Respect Validation 长度校验器 Length 深入解析从基础用法到源码原理 本指南围绕 PHP 验证库 Respect Validation后端开发工具Respect\Validation 邮箱校验器Email Validator完全指南从基础用法到源码级原理Respect\Validation 邮箱校验器Email Validator完全指南从基础用法到源码级原理 本指南以 Respect\Validatio后端开发工具Respect Validation 中的 GreaterThanOrEqual 校验器从 API 用法到比较运算的源码级剖析Respect Validation 中的 GreaterThanOrEqual 校验器从 API 用法到比较运算的源码级剖析 Respect Validat后端开发工具上一篇Kata Containers API 设计解析从 Sandbox 操作到 VM 插件框架下一篇WinFsp 内存文件系统示例解析memfs-fuse3 的构建方式与 FUSE3 实现原理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。