后端开发工具【免费下载链接】ValidationThe most awesome validation engine ever created for PHP项目地址https://gitcode.com/gh_mirrors/va/Validation点击查看免费下载导读v::keySet()是 Respect Validation当前仓库gh_mirrors/va/ValidationPHP 项目中用于按预定义结构校验数组键的组合型验证器它既能逐键执行对应值验证又能拒绝未声明的多余键、追查缺失的必选键并内置了区分多余键 / 缺失键 / 两者皆有的消息模板体系。读完本文你将掌握keySet()的完整构造签名、与key()/keyExists()/keyOptional()的搭配方式、链式构建写法、not()不可否定约束、模板定制以及其底层求值原理含 10 个多余键的上限与短路求值机制。KeySet 是什么验证键的结构而非单个键单个的 Key、KeyExists只负责校验某一个键而keySet()负责把一组键规则打包成一个整体结构契约。它属于本仓库文档分类中的Arrays / Nesting / Structures类验证器是处理嵌套数据结构例如表单提交、API 请求体、配置文件解析结果的首选工具。官方文档给出了两种构造签名KeySet(Validator $validator)KeySet(Validator $validator, Validator ...$validators)第一个参数必填后续参数可变意味着你可以传入一个或多个与键相关的规则。最小可用的例子v::keySet(v::key(foo, v::intVal()))-assert([foo 42]); // Validation passes successfully也可以传入多个只关心键是否存在的规则v::keySet( v::keyExists(foo), v::keyExists(bar) )-assert([foo whatever, bar something]); // Validation passes successfully构造参数的本质只接受与键相关的规则从源码实现看KeySet的构造函数并不会原样保存传入的验证器而是通过私有方法extractKeyRelatedValidators()见 src/Validators/KeySet.php对它们做强制过滤实现KeyRelated接口的验证器Key、KeyExists、KeyOptional会被直接收集传入ValidatorBuilder即v::init()返回的构建器时会递归展开其内部的所有规则再逐一过滤传入其他任何验证器如v::intVal()、v::stringType()会抛出InvalidValidatorException异常消息为You must provide only key-related rules。KeyRelated接口定义在 src/Validators/Core/KeyRelated.php只要求实现getKey(): int|string。正因为构造参数被统一收敛为键相关规则keySet()才能计算出全部键集合与必选键集合$this-allKeys array_map(static fn(KeyRelated $v) $v-getKey(), $this-validators); $this-mandatoryKeys array_map( static fn(KeyRelated $v) $v-getKey(), array_filter($this-validators, static fn(KeyRelated $v) !$v instanceof KeyOptional), );注意KeyOptional声明的键会被计入allKeys出现时允许、需校验值但不会被计入mandatoryKeys缺失时不算错误。核心行为一多余键不被允许keySet()是严格的白名单结构校验——只要输入数组出现了规则集合之外的键就会失败v::keySet( v::key(foo, v::intVal()) )-assert([foo 42, bar String]); // → .bar must not be present错误信息中的.bar是键路径表示法keySet()会把每个键包装成带路径的结果Path对象会在结果中以.key形式呈现。核心行为二缺失必选键不被允许只声明key()而非keyOptional()的键都是必选的缺失即失败v::keySet( v::key(foo, v::intVal()), v::key(bar, v::stringType()), v::key(baz, v::boolType()) )-assert([foo 42, bar String]); // → .baz must be present核心行为三缺失可选键允许把非必填键包装进keyOptional()实现见 src/Validators/KeyOptional.php后缺失时校验直接通过若键存在则委托给内部的Key验证器正常校验值v::keySet( v::key(foo, v::intVal()), v::key(bar, v::stringType()), v::keyOptional(baz, v::boolType()) )-assert([foo 42, bar String]); // Validation passes successfully链式构建把 key 规则合并成一个 ValidatorBuilder不需要把规则一个个平铺传入——你可以先用v::init()开启一条key()链再整体传给keySet()二者等价v::keySet( v::init() -key(foo, v::intVal()) -key(bar, v::stringType()) -keyOptional(baz, v::boolType()) )-assert([foo 42, bar String]); // Validation passes successfully这正是前面提到的extractKeyRelatedValidators()递归展开ValidatorBuilder的场景构建器里的规则被逐一取出并过滤非键规则同样会触发InvalidValidatorException。不能与 not() 组合使用官方文档明确指出keySet()无法被not()否定。这与Not验证器的实现有关——src/Validators/Not.php 在求值时先检查结果是否isIndeterminate不确定若是则原样返回不取反而keySet()这类结构型组合验证器产生的结果会被标记为不确定Result中通过isIndeterminate标志实现见 src/Result.php 的置位逻辑因此not(v::keySet(...))无法得到有意义的否定语义。这也是变更记录中 2.3.0 版本标注KeySet is NonNegatable的原因。键顺序不敏感keySet()只关心键集合的匹配不关心输入数组中键的先后顺序。你可以任意调整[foo ..., bar ...]的书写顺序校验结果不变。底层求值原理ArrayType 前置检查 Reducer 组合keySet()的evaluate()实现src/Validators/KeySet.php分四步先验类型用ArrayType验证输入本身是否为数组。不是数组时直接返回失败结果对应消息not-an-array must be an array。合并所有子规则把所有键相关验证器与为每个多余键动态生成的new Not(new KeyExists($key))一起交给Reducer组合求值。Reducersrc/Validators/Core/Reducer.php在只有一个规则时直接求值多个规则时包装成AllOf。挑选消息模板调用getTemplateFromKeys()根据输入键与allKeys/mandatoryKeys的差集在TEMPLATE_STANDARD、TEMPLATE_EXTRA_KEYS、TEMPLATE_MISSING_KEYS、TEMPLATE_BOTH四者中选择src/Validators/KeySet.php。组装结果将子结果作为 children 挂到根结果上从而支持完整的多层错误消息树。一个值得注意的实现细节常量MAX_DIFF_KEYS 10src/Validators/KeySet.php限制了多余键的报告数量。当输入包含超过 10 个多余键时只对前 10 个生成must not be present错误其余忽略feature 测试one rule / more than ten extra keys覆盖了这一行为。这是防错误消息爆炸的保护性设计而非允许多余键存在。消息模板四套预置模板与占位符keySet()通过 PHP 8 的#[Template]属性注册了四套模板对应源码 src/Validators/KeySet.php 的四个属性声明KeySet::TEMPLATE_STANDARD通用失败模板ModeTemplatedefault{{subject}} validation failedinverted{{subject}} validation passedKeySet::TEMPLATE_BOTH同时存在多余键与缺失键ModeTemplatedefault{{subject}} contains both missing and extra keysinverted{{subject}} contains no missing or extra keys.KeySet::TEMPLATE_EXTRA_KEYS仅存在多余键ModeTemplatedefault{{subject}} contains extra keysinverted{{subject}} contains no extra keysKeySet::TEMPLATE_MISSING_KEYS仅存在缺失键ModeTemplatedefault{{subject}} contains missing keysinverted{{subject}} contains no missing keys模板占位符PlaceholderDescriptionsubjectThe validated input or the custom validator name (if specified).getTemplateFromKeys()决定实际使用哪套模板既有多余键又有缺失键 →TEMPLATE_BOTH只有多余键 →TEMPLATE_EXTRA_KEYS只有缺失键 →TEMPLATE_MISSING_KEYS全部通过 →TEMPLATE_STANDARD。四套模板的根消息会作为__root__键出现在消息数组中子键错误以.key形式挂在 children 上。短路求值short-circuit行为keySet()实现了ShortCircuitable接口并复用CanEvaluateShortCircuittraitsrc/Validators/KeySet.php。在v::shortCircuit()包装下依次求值每个键规则遇到第一个失败立即返回不再继续全部键规则通过后再检查多余键遇到第一个多余键即返回must not be present输入不是数组时直接返回 ArrayType 失败。对应的 feature 测试tests/feature/Validators/KeySetTest.php 的short-circuit / *系列验证了首个键失败、第二个/第三个键失败、多余键先于后续键、缺失键先于多余键、以及嵌套 keySetv::key(user, v::keySet(...))均能正确短路且嵌套路径会拼接为.user.email这种完整路径。与其他验证器及构建器的配合嵌套结构keySet()可嵌套使用v::key(user, v::keySet(...))是校验用户对象这类复杂子结构的典型写法顶层配合可与 ArrayVal、v::key()等数组/键验证器组合构建多层级数据契约构建器入口v::init()-key(...)链在传入keySet()前只是普通构建器因此同一段链式代码既可独立使用也可作为keySet()的参数复用。Categorization分类按官方文档归类keySet()属于ArraysNestingStructuresChangelog变更历史VersionDescription3.0.0Requires at least one key-related validator2.3.0KeySet is NonNegatable, fixed message with extra keys1.0.0Created其中 3.0.0 的至少需要一个键相关验证器对应源码中构造函数强制过滤 InvalidValidatorException的设计2.3.0 的NonNegatable对应上文not()不可组合的语义以及TEMPLATE_EXTRA_KEYS的引入。补充阅读Key为单个键绑定值验证器ArrayVal先确认输入是数组/可迭代结构实现源码src/Validators/KeySet.php、src/Validators/Key.php、src/Validators/KeyOptional.php、src/Validators/KeyExists.php功能测试tests/feature/Validators/KeySetTest.php覆盖单规则/多规则、多余键、缺失键、10 键上限、短路求值与嵌套场景赞分享后端开发工具【免费下载链接】ValidationThe most awesome validation engine ever created for PHP项目地址https://gitcode.com/gh_mirrors/va/Validation点击查看免费下载相关推荐Respect Validation FloatType 验证器PHP 浮点类型严格校验的完整实践指南Respect Validation FloatType 验证器PHP 浮点类型严格校验的完整实践指南 导读 FloatType 是 Respect Vali后端开发工具Respect/Validation 的 DateTime 校验器从格式匹配到严格日期时间验证的完整指南Respect/Validation 的 DateTime 校验器从格式匹配到严格日期时间验证的完整指南 本文围绕 Respect/Validation 中的后端开发工具Respect\Validation 中的 BoolType 验证器严格校验 PHP 布尔类型Respect\Validation 中的 BoolType 验证器严格校验 PHP 布尔类型 Respect\Validation 是 PHP 生态中一个以后端开发工具上一篇IoT-For-Beginners 智慧农业实战用 6 堂课从土壤传感器到云端物联网农场下一篇使用 Cerebras Inference 实现结构化输出Instructor 与 Cerebras 云端的极速集成指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考