seifkamal/struct-array

此包已被废弃,不再维护。未建议替代包。

数组结构验证

v1.1.0 2020-04-28 11:16 UTC

This package is not auto-updated.

Last update: 2023-01-02 00:25:13 UTC


README

PHP 结构化数组

通过定义数组结构,简化 PHP 数组数据的验证过程。

为什么

我们经常需要接收、验证和处理数据对象。有时,数组可能过于简单,无法完成手头的任务,需要使用多个不愉快的控制结构来验证和设置。此外,创建一个专用的 DTO 类(或更多)可能过于冗余,需要大量的样板代码,同时使错误消息和未来的重构变得更加困难。

在这种情况下,我发现自己渴望一个类似 Go/Rust 的 struct

请参阅文档,以了解更多详细信息。

安装

composer require seifkamal/struct-array

用法

要定义和验证数组数据结构,首先创建一个 Struct - 这需要提供一个 name,用于错误消息,以及一个 interface - 然后使用提供的 Validator 函数将数据与定义的 Struct 进行验证。

Structinterface 是一个数组,包含字符串键(匹配预期的属性名称)和可调用的值。这些值可以是任何可调用的 PHP 实体,并预期接受一个混合类型的 $value 参数,并返回一个 bool。一些有效示例包括

  • is_* 变量处理函数is_stringis_intis_callable 等)
  • 闭包(function ($value): bool {}
  • 具有 __invoke($value): bool 方法的类

示例

以下是一个使用提供的方便的辅助函数编写的示例

<?php

use SK\StructArray\Exception\StructValidationException;

use function SK\StructArray\{
    arrayOf, optional, not, struct, validate
};

$directory = [
    'path' => __DIR__,
    'content' => [
        [
            'header' => 'Greeting',
            'line' => 'Hello',
        ],
    ]
];

try {
    validate($directory, struct('Directory', [
         'path' => 'is_dir',
         'file' => optional('is_file', __DIR__ . '/README.md'),
         'content' => arrayOf(struct('Paragraph', [
             'header' => 'is_string',
             'line' => not('is_null'),
         ])),
     ]));
} catch (StructValidationException $e) {
    echo $e->getMessage() . PHP_EOL;
    return;
}

echo "Path: {$directory['path']}" . PHP_EOL;
echo "File: {$directory['file']}" . PHP_EOL;
// Prints:
// Path: /Users/seifkamal/src/struct-array
// File: /Users/seifkamal/src/struct-array/README.md

您也可以直接使用数组,而无需创建 Struct

<?php

use function SK\StructArray\{
    arrayOf, optional, not, validate
};

$directory = [...];

validate($directory, [
    'path' => 'is_dir',
    'file' => optional('is_file', __DIR__ . '/README.md'),
    'content' => arrayOf([
        'header' => 'is_string',
        'line' => not('is_null'),
    ]),
]);

此方法针对快速使用而定制,因此假设定义的接口不是详尽的(即提交给验证的数组允许有未在此定义的键)。这也意味着错误消息将更加通用,即您将看到

Struct 验证失败。 ...

而不是

目录验证失败。 ...

以下是一个直接使用静态类方法的示例

<?php

use SK\StructArray\Exception\StructValidationException;
use SK\StructArray\Property\Type;
use SK\StructArray\Struct;
use SK\StructArray\Validator;

$directory = [
    'path' => __DIR__,
    'content' => [
        [
            'header' => 'Greeting',
            'line' => 'Hello',
        ],
    ]
];

$paragraphStruct = Struct::of('Paragraph', [
     'header' => 'is_string',
     'line' => Type::not('is_null'),
]);
$directoryStruct = Struct::of('Directory', [
     'path' => 'is_dir',
     'file' => Type::optional('is_file', __DIR__ . '/README.md'),
     'content' => Type::arrayOf($paragraphStruct),
]);

try {
    Validator::validate($directory, $directoryStruct);
} catch (StructValidationException $e) {
    echo $e->getMessage() . PHP_EOL;
    return;
}

echo "Path: {$directory['path']}" . PHP_EOL;
echo "File: {$directory['file']}" . PHP_EOL;
// Prints:
// Path: /Users/seifkamal/src/struct-array
// File: /Users/seifkamal/src/struct-array/README.md

更多信息,请参阅示例目录