chevere/parameter

参数-参数库

1.0.2 2024-05-16 17:24 UTC

This package is auto-updated.

Last update: 2024-09-20 00:00:52 UTC


README

🔔 订阅 通讯,不错过任何关于 Chevere 的更新。

Chevere

Build Code size Apache-2.0 PHPStan Mutation testing badge

Quality Gate Status Maintainability Rating Reliability Rating Security Rating Coverage Technical Debt CodeFactor

摘要

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);

使用 reflectionToParametersreflectionToReturn 函数进行参数和返回值的手动验证

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 创建与 01 字符串匹配的 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。传递整数范围的 minmax 值,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 创建与 01 整数匹配的 IntParameter

use function Chevere\Parameter\boolInt;

$bool = boolInt();
$bool(0);
$bool(1);

浮点数

使用函数 float 创建 FloatParameter。传递浮点数范围的 minmax 值,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。传递 VK 参数作为泛型键和值。

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 中定义的 nameid 键。

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 将包含 idsize

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 将产生 sizename 键。

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 将包含 sizename 键。

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 从实现 ParameterAccessInterfaceParametersInterface 的对象中检索一个 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

使用函数 reflectionToParametersReflectionFunctionReflectionMethod 实例检索一个 Parameters 实例。

use function Chevere\Parameter\reflectionToParameters;

$parameters = reflectionToParameters($reflection);

reflectionToReturn

使用函数 reflectionToReturnReflectionFunctionReflectionMethod 实例检索一个 ParameterInterface 实例。

use function Chevere\Parameter\reflectionToReturn;

$parameter = reflectionToReturn($reflection);

reflectedParameterAttribute

使用函数 reflectedParameterAttributeReflectionParameter 实例检索实现 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() 触发参数的验证。

  • 验证字符串枚举 HugoPacoLuis
  • 验证最小浮点值为 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);
  • 验证除 0100 之外的所有整数值
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

除非适用法律要求或书面同意,否则在许可证下分发的软件按“原样”基础分发,不提供任何明示或暗示的保证或条件。有关许可证的具体语言规定权限和限制,请参阅许可证。