neunerlei / options
一个小助手,可以用于将模式应用于任何给定的数组
Requires
- php: ^7.3
Requires (Dev)
- neunerlei/dbg: ^1.9.2
- phpunit/phpunit: ^9.0
README
这个小巧的助手可以用于将模式应用于任何给定的数组。它设计为方法选项的即时验证器,但也足够强大,可以验证各种API请求。
安装
使用composer安装此包
composer require neunerlei/options
基本用法
该包的主要目的是验证传递给方法或函数的选项,如下面基本示例所示
use Neunerlei\Options\Options; function myFunc(array $options = []){ // Apply the options $options = Options::make($options, [ "foo" => 123, "bar" => null, ]); print_r($options); } myFunc(); // Prints: ["foo" => 123, "bar" => null] myFunc(["bar" => "baz"]); // Prints: ["foo" => 123, "bar" => "baz"] myFunc(["baz" => 234]); // This will cause an exception, because the key "baz" is not known
简单定义
如上所示,您可以定义一个简单的键列表和相应的默认值,它们的作用类似于 "array_merge"。传递给 $options 的所有不在定义中的键将抛出验证异常。一般来说,您可以传递任何值作为默认值(数组需要一点技巧,见下文);
定义数组作为默认值
请注意,无法像其他类型一样传递数组作为默认值。您必须确保您的默认数组被一个外部的数组包围,如下所示
use Neunerlei\Options\Options; $options = Options::make($options, [ "foo" => [["my" => "defaultValue"]] ]);
如果您没有将默认数组包裹在数组中,将抛出 InvalidOptionDefinitionException。
高级定义
除了简单的默认值之外,您还可以在定义数组中使用数组作为值。在其中,您可以设置以下选项以验证并按需处理选项。
我选择数组作为定义,因为它们运行速度快,只需要记住少量选项。
选项
default (mixed|callable)
这是当 $options 中的键未指定时使用的默认值。如果未设置,则选项键是必需的!如果默认值是闭包,则调用闭包,并使用其结果作为值。
use Neunerlei\Options\Options; // Simple value default $options = Options::make($options, [ "foo" => [ "default" => 123 ] ]); // Closure result value default $options = Options::make($options, [ "foo" => [ "default" => function($key, $options, $node, $context){ return 123; } ] ]);
type (string|array)
允许对输入进行基本类型验证。它可以是字符串或字符串数组。如果提供了多个值作为数组,它们将通过 OR 运算符连接。可能的值包括
- boolean
- bool
- true
- false
- integer
- int
- double
- float
- number (int and float)
- numeric (both int and float + string numbers -> is_numeric)
- string
- resource
- null
- callable
还可以根据类或接口名称验证实例的类型。
use Neunerlei\Options\Options; // Simple types $options = Options::make($options, [ "foo" => [ "type" => "string" ] ]); $options = Options::make($options, [ "foo" => [ "type" => "number" ] ]); $options = Options::make($options, [ "foo" => [ "type" => [ "number", "string" ] ] ]); // Class types interface AI {}; class A implements AI {} class B extends A {} $options = Options::make(["foo" => new A()], [ "foo" => [ "type" => [A::class]]]); // OK -> Same class $options = Options::make(["foo" => new B()], [ "foo" => [ "type" => [A::class]]]); // OK -> A is the parent $options = Options::make(["foo" => new B()], [ "foo" => [ "type" => [AI::class]]]); // OK -> AI is implemented by the parent $options = Options::make(["foo" => new A()], [ "foo" => [ "type" => [B::class]]]); // FAIL
preFilter (callable)
在类型验证之前调用的回调。可用于在验证类型之前转换传入的值。
use Neunerlei\Options\Options; $options = Options::make($options, [ "foo" => [ "preFilter" => function($incomingValue, $key, $options, $node, $context){ if(is_string($incomingValue)) {return (int)$incomingValue;} return $incomingValue; } ] ]);
filter (callable)
在类型验证完成后调用的回调。可用于在自定义验证开始之前处理给定的值。
use Neunerlei\Options\Options; $options = Options::make($options, [ "foo" => [ "type" => "int", "filter" => function(int $incomingValue, $key, $options, $node, $context){ return empty($incomingValue) ? 1 : $incomingValue; } ] ]);
validator (callable)
执行给定的可调用对象。函数接收:$value, $key, $options, $node, $context。
- 如果函数返回
FALSE
,则验证失败。 - 如果函数返回
TRUE
,则验证通过。 - 如果函数返回值数组,则将值传递并像传递给 "validator" 的数组一样处理。
- 如果函数返回字符串,则视为自定义错误消息。
use Neunerlei\Options\Options; $options = Options::make($options, [ "foo" => [ "type" => "int", "validator" => function(int $incomingValue, $key, $options, $node, $context){ return TRUE; // Success! return FALSE; // Failed return "Failed to validate something!"; // Failed with custom error message return [123, 234]; // Let the "values" validator decide (see: validator (array)) } ] ]);
validator (string)
如果给定的值是非可调用的字符串,则将其评估为正则表达式
use Neunerlei\Options\Options; $options = Options::make($options, [ "foo" => [ "type" => "string", "validator" => '~^0-9$~' ] ]);
validator (array)
一个基本的验证程序,接收一个可能的值列表,并检查给定的值是否与其中至少一个匹配(或运算符)。
use Neunerlei\Options\Options; $options = Options::make($options, [ "foo" => [ "type" => "int", "validator" => [123, 234] // Only 123 or 234 are allowed values ] ]);
子元素 (数组)
这可以用来对选项树应用嵌套定义。`children` 定义的方式与根级别完全相同。只有当 $options 中的值是数组(或默认值为空数组)时,才会使用子元素。有三种方法来评估子元素
- 验证节点的一个直接、关联的子元素
use Neunerlei\Options\Options; $options = Options::make([], [ "foo" => [ "type" => "array", "default" => [], "children" => [ "childFoo" => 123, "KongFoo" => [ "type" => "string", "default" => "foo!" ] ] ] ]); // $options will look like: // [ // "foo" => [ // "childFoo" => 123, // "KongFoo" => "foo!" // ] // ]
- 验证具有相同结构的子节点列表
use Neunerlei\Options\Options; $options = [ "foo" => [ ["childFoo" => 234], ["KongFoo" => "bar :D"] ] ]; $options = Options::make($options, [ "foo" => [ "type" => "array", "default" => [], "children" => [ // This asterisk defines, that the children are repeatable "*" => [ "childFoo" => 123, "KongFoo" => [ "type" => "string", "default" => "foo!" ] ] ] ] ]); // $options will look like: // [ // "foo" => [ // ["childFoo" => 234, "KongFoo" => "foo!"], // ["childFoo" => 123, "KongFoo" => "bar :D"] // ] // ];
- 验证具有相同类型的值列表(例如电话号码列表)
use Neunerlei\Options\Options; $options = [ "foo" => [ 'HOW', 'ARE', 'YOU' ] ]; $options = Options::make($options, [ "foo" => [ "type" => "array", "default" => [], "children" => [ // This hashtag defines, that we expect repeatable children of the same type "#" => [ 'type' => 'string', 'filter' => function(string $v): string{ return strtolower($v); } 'validator' => ['how', 'are', 'you'] ] ] ] ]); // $options will look like: // [ // "foo" => [ // 'how', 'are', 'you' // ] // ];
布尔标志
还可以提供类型为 "boolean" 的选项作为 "flags",这意味着你不需要提供任何值给它。注意:布尔标志只能用于将布尔值设置为 TRUE;如果你想将其设置为 FALSE,你必须设置键值对。
use Neunerlei\Options\Options; function myFunc(array $options = []){ // Apply the options $options = Options::make($options, [ "foo" => [ "type" => "bool", "default" => false ] ]); print_r($options); } myFunc(); // Prints: ["foo" => false] myFunc(["foo"]); // Prints: ["foo" => true] myFunc(["foo" => true]); // Prints: ["foo" => true]
附加选项
Options::make() 方法的第三个参数允许你定义附加选项。所有布尔值都可以作为键值对或布尔标志传递。
allowUnknown (布尔)
默认值:FALSE
如果设置为 TRUE,未知键将被保留在结果中。
ignoreUnknown (布尔)
默认值:FALSE
如果设置为 TRUE,未知键将被忽略并从结果中删除。
allowBooleanFlags (布尔)
默认值:TRUE
如果设置为 FALSE,则不允许在输入数组中使用布尔标志。这在验证 API 输入时很有用。
单值处理
通常,这与 Options::make() 做的是相同的事情,但它旨在验证非数组选项。
注意:有一个陷阱。正如你在我们的示例中所看到的,我们在签名中将 $anOption 定义为 = null。这会导致方法使用默认值 "foo",如果属性未设置。所以请确保,如果你想允许 NULL 作为非默认值,请使用回调作为默认值并自行处理 NULL。
use Neunerlei\Options\Options; function myFunc($value, $anOption = null){ $anOption = Options::makeSingle("anOption", $anOption, [ "type" => ["string"], "default" => "foo", ]); }
不使用静态类的方法
静态类使用 Neunerlei\Options\Applier\Applier
类的单例来执行所有操作。所以如果你想使用 applier 作为服务并通过依赖注入使用,只需使用 applier 类而不是静态的 Options 类。
扩展 applier 类
静态 Options 类有一个公共、静态属性 $applierClass
,它定义了用于逻辑的类的名称。如果你想扩展功能,你可以简单地扩展 applier 类并将 Options::$applierClass
设置为你的扩展类的名称,然后一切就绪。
特别感谢
特别感谢 LABOR.digital(这是德语中的实验室,而不是英语中的“工作” :D)的人们,使他们能够在线发布我的代码。
明信片软件
你可以自由使用这个包,但如果它进入了你的生产环境,我非常希望你能从你的家乡寄给我一张明信片,说明你正在使用我们的哪个包。
你可以在这里找到我的地址:这里。
谢谢 :D