chevere / parameter
参数-参数库
Requires
- php: ^8.1
- chevere/data-structure: ^1.0.1
- chevere/message: ^1.0.0
- chevere/regex: ^1.0.1
Requires (Dev)
- phpstan/phpstan: ^1.9
- phpunit/phpunit: ^9.5
- symplify/easy-coding-standard: ^11.1
README
🔔 订阅 通讯,不错过任何关于 Chevere 的更新。
摘要
Parameter 是一个围绕参数-参数的库,通过验证规则和模式内省提供了额外的功能。
安装
Parameter 通过 Packagist 提供支持,仓库源代码位于 chevere/parameter。
composer require chevere/parameter
它能做什么?
Parameter 允许使用额外的规则生成任何类型的动态参数。
例如,一个最小值为 10 的整数。
use function Chevere\Parameter\int; $int = int(min: 10); $int($var); // exception if $var < 10
在函数或方法参数中,您可以使用属性来定义参数和返回值的验证规则。
use Chevere\Parameter\Attributes\FloatAttr; use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\ReturnAttr; use function Chevere\Parameter\returnAttr; use function Chevere\Parameter\validated; #[ReturnAttr( new FloatAttr(min: 0, max: 2400) )] function wageWeekWA( #[IntAttr(min: 1628)] int $cents, #[FloatAttr(min: 0, max: 40)] float $hours ) { return $cents*$hours/100; } validated('wageWeekWA', $cents, $hours);
可以使用 validated
(例如上述内容)、内联 和/或 委托 到调用包装器的形式来触发验证。Parameter 提供了辅助器来访问参数和返回值的规则,以简化连接过程。
每个参数定义的规则提供了一种可读的方案,允许暴露验证标准。
如何使用
Parameter 提供了一个 API,可以用于使用函数和/或属性创建参数。Parameter 对象可以直接用于逻辑中,而属性则需要一个读取步骤。
内联使用
使用 内联验证 从这个
if($var > 10 || $var < 1) { throw new InvalidArgumentException(); }
转换到这个
use function \Chevere\Parameter\int; int(min: 1, max: 10)($var);
基于属性的用法
使用属性来定义参数和返回值的规则。
使用 属性委托验证 与 validated()
函数从这个
function myFunction(int $var): string { if($var > 10 || $var < 1) { throw new InvalidArgumentException(); } $return = 'done ok'; return preg_match('/ok$/', $return) ? $return : throw new InvalidArgumentException(); } $result = myFunction($var);
转换到这个
use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\ReturnAttr; use Chevere\Parameter\Attributes\StringAttr; use function Chevere\Parameter\validated; #[ReturnAttr( new StringAttr('/ok$/') )] function myFunction( #[IntAttr(min: 1, max: 10)] int $var ): string { return 'done ok'; } $result = validated('myFunction', $var);
使用 reflectionToParameters
和 reflectionToReturn
函数进行参数和返回值的手动验证
use ReflectionFunction; use function Chevere\Parameter\reflectionToParameters; use function Chevere\Parameter\reflectionToReturn; $reflection = new ReflectionFunction('myFunction'); $parameters = reflectionToParameters($reflection); $return = reflectionToReturn($reflection); $parameters(...$args); // valid $args $result = myFunction(...$args); // myFunction call $return($result); // valid $result
使用 属性内联验证 在函数体内部进行手动验证
use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\ReturnAttr; use Chevere\Parameter\Attributes\StringAttr; use function Chevere\Parameter\valid; use function Chevere\Parameter\returnAttr; #[ReturnAttr( new StringAttr('/ok$/') )] function myFunction( #[IntAttr(min: 1, max: 10)] int $var ): string { valid(); // valid $var $return = 'ok'; return returnAttr()($return); // valid $return }
CallableAttr
PHP 中的属性仅支持您可以在类常量上使用的表达式。不能直接使用属性定义动态参数。
为了避免这种限制,您可以使用 CallableAttr
属性,它可以将参数解析委托给返回 ParameterInterface
实例的可调用对象。
use Chevere\Parameter\Interfaces\ParameterInterface; use Chevere\Parameter\Attributes\CallableAttr; function myCallable(): ParameterInterface { return arrayp( email: string(), )->withOptional( name: string(), ); } #[CallableAttr('myCallable')]
类型
Parameter 是一个实现 ParameterInterface
的对象。每个 Parameter 都可以定义一个 description
和一个 default
值,以及根据类型定义的附加验证规则。
Parameter 可以使用函数和/或属性定义,它对两者都使用相同的参数。
调用 Parameter $param('value')
时,将触发对传入参数的验证。
字符串
使用函数 string
创建 StringParameter
。传递一个用于字符串匹配的正则表达式。
use function Chevere\Parameter\string; // Any string $string = string(); // String matching bin-<digits> $string = string('/^bin-[\d]+$/'); $string('bin-123');
使用 StringAttr
属性定义字符串参数。
use Chevere\Parameter\Attributes\StringAttr; #[StringAttr('/^bin-[\d]+$/')]
字符串伪参数
以下参数基于字符串。
枚举字符串
使用函数 enum
创建与字符串列表匹配的 StringParameter
。
use function Chevere\Parameter\enum; $enum = enum('on', 'off'); $enum('on'); $enum('off');
使用 EnumAttr
属性来定义枚举字符串参数。
use Chevere\Parameter\Attributes\EnumAttr; #[EnumAttr('on', 'off')]
字符串整数
使用函数 intString
创建与字符串整数匹配的 StringParameter
。
use function Chevere\Parameter\intString; $int = intString(); $int('100');
布尔字符串
使用函数 boolString
创建与 0
和 1
字符串匹配的 StringParameter
。
use function Chevere\Parameter\boolString; $bool = boolString(); $bool('0'); $bool('1');
日期字符串
使用函数 date
创建与 YYYY-MM-DD
字符串匹配的 StringParameter
。
use function Chevere\Parameter\date; $date = date(); $date('2021-01-01');
时间字符串
使用函数 time
创建与 hh:mm:ss
字符串匹配的 StringParameter
。
use function Chevere\Parameter\time; $time = time(); $time('12:00:00');
日期时间字符串
使用函数 datetime
创建与 YYYY-MM-DD hh:mm:ss
字符串匹配的 StringParameter
。
use function Chevere\Parameter\datetime; $datetime = datetime(); $datetime('2024-01-09 10:53:00');
整数
使用函数 int
创建 IntParameter
。传递整数范围的 min
和 max
值,accept
为接受整数列表,reject
为拒绝整数列表。
use function Chevere\Parameter\int; // Any int $int = int(); $int(1); // Integer between 0 and 100 $int = int(min: 0, max: 100); $int(50); // Integer matching 1, 2 or 3 $int = int(accept: [1, 2, 3]); $int(2); // Integer not-matching 1, 2 or 3 $int = int(reject: [1, 2, 3]); $int(4);
使用 IntAttr
属性定义整数参数。
use Chevere\Parameter\Attributes\IntAttr; #[IntAttr(min: 0, max: 100)]
整数伪参数
以下参数基于整数。
布尔整数
使用函数 boolInt
创建与 0
和 1
整数匹配的 IntParameter
。
use function Chevere\Parameter\boolInt; $bool = boolInt(); $bool(0); $bool(1);
浮点数
使用函数 float
创建 FloatParameter
。传递浮点数范围的 min
和 max
值,accept
为接受浮点数列表,reject
为拒绝浮点数列表。
use function Chevere\Parameter\float; // Any float $float = float(); $float(1.5); // Float between 0 and 100 $float = float(min: 0, max: 100); $float(50.5); // Float matching 1.5, 2.5 or 3.5 $float = float(accept: [1.5, 2.5, 3.5]); $float(2.5); // Float not-matching 1.5, 2.5 or 3.5 $float = float(reject: [1.5, 2.5, 3.5]); $float(4.5);
使用 FloatAttr
属性定义浮点数参数。
use Chevere\Parameter\Attributes\FloatAttr; #[FloatAttr(min: 0, max: 100)]
布尔值
使用函数 bool
创建 BoolParameter
。
use function Chevere\Parameter\bool; $bool = bool(); $bool(true); $bool(false);
使用 BoolAttr
属性定义布尔参数。
use Chevere\Parameter\Attributes\BoolAttr; #[BoolAttr]
空值
使用函数 null
创建 NullParameter
。
use function Chevere\Parameter\null; $null = null(); $null(null);
使用 NullAttr
属性定义空参数。
use Chevere\Parameter\Attributes\NullAttr; #[NullAttr]
对象
使用函数 object
创建 ObjectParameter
。传递对象类的类名。
use function Chevere\Parameter\object; $object = object(stdClass::class); $object(new stdClass());
使用 ObjectAttr
属性定义对象参数。
use Chevere\Parameter\Attributes\ObjectAttr; #[ObjectAttr(stdClass::class)]
混合
使用函数 mixed
创建 MixedParameter
。
use function Chevere\Parameter\mixed; $mixed = mixed(); $mixed(1); $mixed('1'); $mixed(true); $mixed(null);
联合
使用函数 union
创建 UnionParameter
。传递要匹配的参数列表,目标值必须匹配至少一个。
use function Chevere\Parameter\union; // Any string or null $union = union(string(), null()); $union('abc'); $union(null); // Any digit string or any integer $union = union( intString(), integer() ); $union('100'); $union(100);
数组
类型为 array
的参数被视为一个复合参数,包含其每个成员的参数定义。
使用函数 arrayp
创建具有所需数组键命名的 ArrayParameter
。
use function Chevere\Parameter\arrayp; // Empty array $array = arrayp(); $array([]); // Required 'a' => <string> $array = arrayp(a: string()); $array(['a' => 'Hello world']);
支持任何深度的嵌套数组
use function Chevere\Parameter\arrayp; use function Chevere\Parameter\float; use function Chevere\Parameter\int; $array = arrayp( id: int(min: 0), items: arrayp( id: int(min: 0), price: float(min: 0), ), ); $array([ 'id' => 1, 'items' => [ 'id' => 25, 'price' => 16.5, ] ]);
使用 ArrayAttr
属性定义数组参数。
use Chevere\Parameter\Attributes\ArrayAttr; use Chevere\Parameter\Attributes\FloatAttr; use Chevere\Parameter\Attributes\IntAttr; #[ArrayAttr( id: new IntAttr(), items: new ArrayAttr( id: new IntAttr(), price: new FloatAttr(), ), )]
需要时
使用方法 withRequired
定义必需参数。
$array = $array ->withRequired( username: string(), email: string() );
可选时
使用方法 withOptional
定义可选参数。
$array = $array ->withOptional(address: string());
👉 注意: 只有当提供匹配的键时,才会验证可选参数。
修改时
使用方法 withModify
定义修改参数。
$array = $array ->withModify( username: string('/\w+/'), );
使可选
使用方法 withMakeOptional
使必需参数可选。
$array = $array ->withMakeOptional('username');
使必需
使用方法 withMakeRequired
使可选参数必需。
$array = $array ->withMakeRequired('email');
无
使用方法 without
删除参数。
$array = $array ->without('a');
可选最小值
使用方法 withOptionalMinimum
定义可选参数的最小数量。如果有所有参数都是可选的,但只有一个时很有用。
$array = $array ->withOptionalMinimum(1);
数组伪参数
以下参数基于数组。
数组字符串
使用函数 arrayString
创建用于字符串值的 ArrayStringParameterInterface
。它仅支持字符串参数。
use function Chevere\Parameter\arrayString; use function Chevere\Parameter\string; $array = arrayString( test: string(), ); $array(['test' => 'foo']);
文件
使用函数 file
创建用于文件上传的 ArrayParameter
。
use function Chevere\Parameter\file; $array = file(); $file = [ 'name' => 'foo.txt', 'type' => 'text/plain', 'tmp_name' => '/tmp/phpYzdqkD', 'error' => 0, 'size' => 123, ]; $array($file);
默认情况下,它提供了对 $_FILES
形状的验证,但您可以定义自己的验证规则。例如,验证名称和内容
use function Chevere\Parameter\file; $array = file( name: string('/^\.txt$/'), contents: string('/wage-/'), ); $array( 'name' => 'wage-2024.txt', 'type' => 'text/plain', 'tmp_name' => '/tmp/phpYzdqkD', 'error' => 0, 'size' => 27, 'contents' => 'yada yada wage-2024 bla bla', );
可迭代的
可迭代类型 Traversable|array
被视为一个复合参数,包含键和值的泛型定义。参数允许描述具有相同形状的项目集合。
使用函数 iterable
创建一个 IterableParameter
。传递 V
和 K
参数作为泛型键和值。
use function Chevere\Parameter\int; use function Chevere\Parameter\iterable; $iterable = iterable(int(min: 0)); $iterable([0, 1, 2, 3]);
它也支持命名键
use function Chevere\Parameter\int; use function Chevere\Parameter\iterable; use function Chevere\Parameter\string; $iterable = iterable( V: arrayp( id: int(min: 0), name: string('^[\w]{1,255}'), ) K: string(), ); $iterable([ 'based' => [ 'id' => 1, 'name' => 'OscarGangas' ], 'fome' => [ 'id' => 2, 'name' => 'BomboFica' ], ]);
辅助函数
参数
使用函数 parameters
创建一个 Parameters
实例。
use function Chevere\Parameters\parameters; use function Chevere\Parameters\string; $parameters = parameters(foo: string());
参数
使用函数 arguments
创建一个 Arguments
实例。
use function Chevere\Parameters\arguments; use function Chevere\Parameters\string; $arguments = arguments($parameters, ['foo' => 'bar']);
assertNamedArgument
使用函数 assertNamedArgument
断言一个命名参数。
use function Chevere\Parameters\assertNamedArgument; use function Chevere\Parameters\int; use function Chevere\Parameters\parameters; $parameter = int(min: 10); assertNamedArgument( name: 'foo', parameter: $parameter, argument: 20 );
toParameter
使用函数 toParameter
从类型字符串创建一个 ParameterInterface
实例。在下面的示例中,结果 $parameter
将是一个 IntParameter
。
use function Chevere\Parameters\toParameter; $parameter = toParameter('int');
arrayFrom
使用函数 arrayFrom
从另一个数组参数创建一个 数组参数。在下面的示例中,结果 $array
将仅包含在 $source
中定义的 name
和 id
键。
use function Chevere\Parameters\arrayFrom; use function Chevere\Parameters\arrayp; use function Chevere\Parameters\int; use function Chevere\Parameters\string; $source = arrayp( id: int(), name: string(), email: string(), age: int(), ); $array = arrayFrom($source, 'name', 'id');
takeKeys
使用函数 takeKeys
从参数检索包含键的数组。在下面的示例中,$keys
将包含 id
和 size
。
use function Chevere\Parameters\arrayp; use function Chevere\Parameters\int; use function Chevere\Parameters\takeKeys; $array = arrayp( id: int(), size: int(), ); $keys = takeKeys($array);
takeFrom
使用函数 takeFrom
从参数检索包含所需键的迭代器。在下面的示例中,$iterator
将产生 size
和 name
键。
use function Chevere\Parameters\arrayp; use function Chevere\Parameters\int; use function Chevere\Parameters\string; use function Chevere\Parameters\takeFrom; $array = arrayp( id: int(min: 0), size: int(min: 100), name: string(), ); $iterator = takeFrom($array, 'size', 'name');
parametersFrom
使用函数 parametersFrom
从参数创建一个包含所需键的 Parameters
。在下面的示例中,$parameters
将包含 size
和 name
键。
use function Chevere\Parameters\arrayp; use function Chevere\Parameters\int; use function Chevere\Parameters\string; use function Chevere\Parameters\parametersFrom; $array = arrayp( id: int(min: 0), size: int(min: 100), name: string(), ); $parameters = parametersFrom($array, 'size', 'name');
getParameters
使用函数 getParameters
从实现 ParameterAccessInterface
或 ParametersInterface
的对象中检索一个 Parameters
实例。
use function Chevere\Parameters\getParameters; $parameters = getParameters($object);
getType
使用函数 getType
获取该库所知的类型。
use function Chevere\Parameters\getType; $type = getType(1); // int
parameterAttr
使用函数 parameterAttr
从函数或类方法参数检索实现 ParameterAttributeInterface
的对象。
use function Chevere\Parameters\parameterAttr; use Chevere\Parameter\Attributes\StringAttr; function myFunction( #[StringAttr('/^bin-[\d]+$/')] string $foo ): void { // ... } $stringAttr = parameterAttr('foo', 'myFunction'); $stringAttr('bin-123');
reflectionToParameters
使用函数 reflectionToParameters
从 ReflectionFunction
或 ReflectionMethod
实例检索一个 Parameters
实例。
use function Chevere\Parameter\reflectionToParameters; $parameters = reflectionToParameters($reflection);
reflectionToReturn
使用函数 reflectionToReturn
从 ReflectionFunction
或 ReflectionMethod
实例检索一个 ParameterInterface
实例。
use function Chevere\Parameter\reflectionToReturn; $parameter = reflectionToReturn($reflection);
reflectedParameterAttribute
使用函数 reflectedParameterAttribute
从 ReflectionParameter
实例检索实现 ParameterAttributeInterface
的对象。
use function Chevere\Parameter\reflectedParameterAttribute; $parameterAttribute = reflectedParameterAttribute($reflectionParameter);
validated
使用函数 validated
验证函数或方法的参数。
use function Chevere\Parameter\validated; $result = validated('myFunction', $arg1, $arg2,);
示例
内联验证
- 验证以 "a" 开头的字符串
use function Chevere\Parameter\string; $value = 'ahhh'; string('/^a.+/')($value);
- 验证最小值为
100
的整数
use function Chevere\Parameter\int; $value = 100; int(min: 100)($value);
- 验证接受列表的整数
use function Chevere\Parameter\int; $value = 1; int(accept: [1, 2, 3])($value);
- 验证拒绝列表的浮点数
use function Chevere\Parameter\float; $value = 3.1; float(reject: [1.1, 2.1])($value);
- 验证数组
use function Chevere\Parameter\arrayp; use function Chevere\Parameter\int; use function Chevere\Parameter\string; $value = [ 'id' => 1, 'name' => 'Pepe' ]; arrayp( id: int(min: 1), name: string('/^[A-Z]{1}\w+$/') )($value);
- 验证
int
列表的迭代器
use function Chevere\Parameter\int; use function Chevere\Parameter\iterable; $value = [1, 2, 3]; iterable(int())($value);
- 验证具有字符串键类型规则的迭代器
int
列表
use function Chevere\Parameter\int; use function Chevere\Parameter\iterable; $value = [ 'unila' => 1, 'dorila' => 2, 'tirifila' => 3, ]; iterable( K: string('/ila$/'), V: int(min: 1) )($value);
- 验证类型为 ?int 的联合
use function Chevere\Parameter\int; use function Chevere\Parameter\null; $value = 1; union(int(), null())($value);
属性委托验证
- 使用函数
validated()
获取经过所有规则验证的返回值。
use function Chevere\Parameter\validated; $result = validated('myFunction', $var);
- 使用函数
reflectionToParameters()
获取验证参数的规则。
use ReflectionMethod; use Chevere\Parameter\Attributes\IntAttr; use function Chevere\Parameter\arguments; use function Chevere\Parameter\reflectionToParameters; $class = new class() { public function wea( #[IntAttr(accept: [1, 10, 100])] int $base ): void { } }; $object = new $class(); $reflection = new ReflectionMethod($object, 'wea'); $parameters = reflectionToParameters($reflection); $args = ['base' => 10]; $parameters(...$args); // valid $args $result = $object->wea(...$args);
- 使用函数
reflectionToReturn()
获取验证函数/方法返回值的规则
use ReflectionFunction; use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\ReturnAttr; use function Chevere\Parameter\reflectionToReturn; $function = #[ReturnAttr( new IntAttr(min: 1000) )] function (int $base): int { return 10 * $base; }; $reflection = new ReflectionFunction($function); $return = reflectionToReturn($reflection); $base = 10; $result = $function($base); $result = $return($result); // Validates result
属性内联验证
在函数/方法体上使用 valid()
触发参数的验证。
- 验证字符串枚举
Hugo
、Paco
、Luis
- 验证最小浮点值为
1000
use Chevere\Parameter\Attributes\EnumAttr; use function Chevere\Parameter\validate; function myEnum( #[EnumAttr('Hugo', 'Paco', 'Luis')] string $name, #[FloatAttr(min: 1000)] float $money ): void { valid(); // Or single... valid('name'); valid('money'); } $arg1 = 'Paco'; $arg2 = 1000.50; myEnum($arg1, $arg2);
- 验证除
0
和100
之外的所有整数值
use Chevere\Parameter\Attributes\IntAttr; use function Chevere\Parameter\validate; function myInt( #[IntAttr(reject: [0, 100])] int $id ): void { valid(); } $value = 50; myInt($value);
- 验证嵌套数组
use Chevere\Parameter\Attributes\ArrayAttr; use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\StringAttr; use Chevere\Parameter\Attributes\IterableAttr; use function Chevere\Parameter\validate; function myArray( #[ArrayAttr( id: new IntAttr(min: 1), role: new ArrayAttr( mask: new IntAttr(accept: [64, 128, 256]), name: new StringAttr('/[a-z]+/'), tenants: new IterableAttr( new IntAttr(min: 1) ) ), )] array $spooky ): void { valid(); } $value = [ 'id' => 10, 'role' => [ 'mask' => 128, 'name' => 'admin', 'tenants' => [1, 2, 3, 4, 5] ], ]; myArray($value);
- 验证迭代器整数列表
use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\IterableAttr; use function Chevere\Parameter\validate; function myIterable( #[IterableAttr( new IntAttr(), )] array $list = [0,1,2] ): void { valid(); }
在函数/方法体上使用 returnAttr()
。
- 验证
min: 0, max: 5
返回的整数
use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\ReturnAttr; use function Chevere\Parameter\returnAttr; #[ReturnAttr( new IntAttr(min: 0, max: 5) )] public function myReturnInt(): int { $result = 1; return returnAttr()($result); }
- 验证返回的数组
use Chevere\Parameter\Attributes\ArrayAttr; use Chevere\Parameter\Attributes\IntAttr; use Chevere\Parameter\Attributes\StringAttr; use Chevere\Parameter\Attributes\ReturnAttr; use function Chevere\Parameter\returnAttr; #[ReturnAttr( new ArrayAttr( id: new IntAttr(min: 0), name: new StringAttr() ) )] public function myReturnArray(): array { $result = [ 'id' => 1, 'name' => 'Peoples Hernandez' ]; return returnAttr()($result); }
💡 按照惯例,在省略 ReturnAttr
时,如果存在,将使用方法 public static function return(): ParameterInterface
来确定返回验证规则。
文档
文档可在 chevere.org 查找。
许可证
版权所有 Rodolfo Berrios A.
Chevere 采用 Apache License,版本 2.0 许可。有关完整的许可文本,请参阅 LICENSE。
除非适用法律要求或书面同意,否则在许可证下分发的软件按“原样”基础分发,不提供任何明示或暗示的保证或条件。有关许可证的具体语言规定权限和限制,请参阅许可证。