一个 PHP 安全数据解析库

1.0.0 2024-06-03 20:50 UTC

This package is auto-updated.

Last update: 2024-09-18 16:42:45 UTC


README

Zec 数据解析和模式声明库旨在为 PHP 应用程序提供模式定义和验证功能。

安装

Composer

composer require mohamed-amine-sayagh/zec

要求

  • PHP 8.0 或更高版本

使用示例

以下是一个如何使用 Zec 库定义和验证用户配置文件模式的示例

定义用户数据验证的方案

    use function Zec\Utils\z;

    // Define the user profile schema
    $userProfileParser = z()->options([
        'name' => z()->string()->min(3)->max(50),  // Name must be a string between 3 and 50 characters
        'age' => z()->number()->min(18),           // Age must be a number and at least 18
        'email' => z()->email(),                   // Email must be a valid email address
        'address' => z()->options([               
            'street' => z()->string(),             
            'city' => z()->string()                
        ]),
        'hobbies' => z()->each(z()->string()),     // Hobbies must be an array of strings
        'metadata' => z()->optional()->each(z()->options([  // Metadata is optional and must be an array of objects
            'key' => z()->string(),                // Each object must have a key as a string
            'value' => z()->string()               // Each object must have a value as a string
        ]))
    ]);

解析用户数据并验证它

    // Parse and validate user data
    $userData = [
        'name' => 'Jane Doe',
        'age' => 1, // 1 is not a valid age
        'email' => 'jane.doe@examplecom', // missing dot
        'address' => [
            'street' => '123 Elm St',
            'city' => 3 // city is not a string
        ],
        'hobbies' => ['photography', 'traveling', 'reading', 5], // 5 is not a string     
        'metadata' => [
            ['key' => 'memberSince', 'value' => '2019'],
            ['key' => 'newsletter', 'value' => 'true']
        ]
    ];

    try {
        $userProfileParser->parseOrThrow($userData); // Throws an error
        echo "User data is valid\n";
    } catch (\Zec\ZecError $e) {
        echo "User data is invalid: ";
        $e->log(); // Log the error
    }

预期的错误响应

    User data is invalid: [
        {
            "parser": "min",
            "value": 1,
            "min": 18,
            "message": "Invalid value",
            "path": [
                "age"
            ]
        },
        {
            "parser": "email",
            "value": "jane.doe@examplecom",
            "message": "Invalid email address",
            "path": [
                "email"
            ]
        },
        {
            "parser": "string",
            "value": 5,
            "message": "Invalid string value",
            "path": [
                "hobbies",
                "3"
            ]
        }
    ]

当前版本: v1.0.0, 发布日期: 2024-10-01, 作者: Mohamed Amine SAYAGH, 发布说明: Zec PHP 数据解析库的初始发布,发布链接: [Zec 1.0.0](

注意: 该库目前处于开发中。官方文档和更多资源将很快提供。

作者信息

目录

一些其他优秀方面

  • 强大的模式验证:提供类似 Zec 库的强类型和验证,确保准确的数据处理。
  • 模块化和可扩展:易于通过自定义解析器扩展,满足多样化的数据验证需求。
  • 关注点分离:将数据处理与业务逻辑分离,以增强安全性和可维护性。
  • 易于测试:通过强制数据验证简化测试。
  • 灵活配置:支持动态解析器配置和自定义,无需修改核心库。
  • 以社区为中心:欢迎贡献,增强集体改进和支持。

协作

我们完全欢迎合作! 如果您有兴趣为 PHP 数据解析库做出贡献,我们非常乐意听取您的意见。无论是通过代码贡献、文档改进还是功能建议,您的意见都备受欢迎。

如何贡献

  1. 分支仓库:首先将仓库分支到您的 GitHub 账户。
  2. 克隆您的分支:将您的分支克隆到本地计算机并设置开发环境。
  3. 创建新分支:在一个新的 git 分支中做出更改。
  4. 提交更改:使用清晰和描述性的提交信息提交您的修改。
  5. 推送更改:将您的更改推送到 GitHub 上的分支。
  6. 提交拉取请求:向我们的仓库主分支提交拉取请求。请提供更改的清晰描述以及任何有助于我们了解您的贡献的其他信息。

有关更多详细信息,请查看我们的贡献指南(如有详细贡献指南的链接)。

我们期待与充满活力的贡献者社区共同构建强大的数据解析工具!

使用

基本解析

使用简单的方案定义定义和验证数据类型

    use function Zec\Utils\z;
    $my_schema = z()->string();
    
    $response_valid = $my_schema->parse("Hello, World!"); // Returns Zec data object
    $value = $response_valid->value; // Returns "Hello, World!"

    $response_invalid = $my_schema->parse(123); // Returns Zec data object
    $errors = $response_invalid->errors; // Returns an array of ZecError object an exception extends class

验证

在解析后快速验证数据

    $is_valid = $my_schema->parse("Hello, World!")->isValid(); // Returns true
    $is_invalid = $my_schema->parse(123)->isValid(); // Returns false

使用解析处理异常

使用 parse_or_throw 处理异常以执行关键数据验证

    try {
        $response = $my_schema->parseOrThrow(123); // Throws ZecError
    } catch (ZecError $error) {
        $error_message = $error->message; // Returns "Invalid type: expected string, received integer"
        $error->log(); // Logs the error
    }

解析选项数组

您可以通过合并额外的验证选项来增强方案定义。这允许根据特定要求对数据一致性进行更详细的控制。

    use function Zec\z;

    $user_schema = z()->options([
        'name' => z()->string()->min(3)->max(50),
        'email' => z()->email(),
        'age' => z()->number()->min(18),
        'isActive' => z()->boolean(),
        'registrationDate' => z()->date()
    ]);

    // Parsing a valid user object
    $valid_user = $user_schema->parse([
        'name' => 'John Doe',
        'email' => 'john.doe@example.com',
        'age' => 30,
        'isActive' => true,
        'registrationDate' => '2021-01-01'
    ]);

    // Parsing an invalid user object
    $invalid_user = $user_schema->parse([
        'name' => 'JD', // Too short
        'email' => 'john.doe@', // Invalid email format
        'age' => 17, // Below minimum age requirement
        'isActive' => 'yes', // Incorrect type (should be boolean)
        'registrationDate' => '01-01-2021' // Wrong date format
    ]);

    // Handling validation results
    if ($valid_user->isValid()) {
        echo 'User is valid.';
    } else {
        echo 'User is invalid. Errors: ';
        var_dump($valid_user->errors());
    }

    if ($invalid_user->isValid()) {
        echo 'User is valid.';
    } else {
        echo 'User is invalid. Errors: ';
        var_dump($invalid_user->errors());
    }

高级解析器配置

该库为数据验证提供了广泛的配置性,允许用户定义复杂的验证规则,包括自定义信息和条件。下面是配置电子邮件字段的详细模式并带有特定验证规则的一个示例。

    use function Zec\z;

    // Define a configurable email schema
    $my_configurable_email_schema = z()->string([
        'message' => 'Invalid string data'
    ])->min([
        'min' => 3,
        'message' => 'String data must be at least 3 characters long' // Custom message
    ])->max([
        'max' => 10,
        'message' => 'String {{value}} must be at most ((max)) characters long' // Custom message with value interpolation
    ]).email([
        'message' => 'Invalid email',
        'domain' => ['gmail.com', 'yahoo.com'] // Custom domain validation rules
    ]);

    // Define a user schema using the configurable email schema
    $my_user = z()->options([
        'email' => $my_configurable_email_schema->required()
    ]);

复杂示例:用户数据验证

此示例演示了验证包含嵌套数组、可选字段和联合类型的用户数据结构,展示了该库处理复杂和真实数据模型的能力。

    use function Zec\z;

    // Define a user schema with various data validation rules
    $user_parser = z()->options([
        'name' => z()->required()->string()->min(3)->max(50),
        'email' => z()->url([
            'message' => 'Invalid email address', 
            'domain' => ['gmail.com']
        ]),
        'age' => z()->number(),
        'friends' => z()->each(
            function ($user) {
                return $user->nullable();
            } // Each friend is a user object (nullable)
        ),
        'password' => z()->optional()->options([
            'password' => z()->string(),  // Path: 'password.password'
            'confirm_password' => z()->string(),
            'created_at' => z()->date(),
        ]),
        'created_at' => z()->date(),
        'updated_at' => z()->date(),
        'document' => z()->union([
            z()->options([
                'type' => z()->enum(['student']),
                'content' => z()->options([
                    'school' => z()->string(),
                    'grade' => z()->number(),
                ]),
            ]),
            z()->options([
                'type' => z()->enum(['teacher']),
                'content' => z()->options([
                    'school' => z()->string(),
                    'subject' => z()->string(),
                ]),
            ]),
        ]) // Union type for document, can be student or teacher document
    ]);

    // Parse a valid user object
    $user = $user_parser->parse([
        'name' => 'John Doe',
        'email' => 'amine@gmail.com',
        'age' => 25,
        'friends' => [
            [
                'name' => 'Jane Doe',
                'email' => 'john@gmail.com',
                'age' => 30,
            ],
        ],
        'password' => [
            'password' => 'password',
            'confirm_password' => 'password',
            'created_at' => '2021-10-10'
        ],
        'created_at' => '2021-10-10',
        'updated_at' => '2021-10-10',
        'document' => [
            'type' => 'student',
            'content' => [
                'school' => 'School',
                'grade' => 10,
            ]
        ]
    ]); // Returns a Zec object

    // Validate the parsed data
    if ($user->isValid()) {
        echo 'User is valid.';
        var_dump($user->getValue()); // Outputs the validated data
    } else {
        echo 'User is invalid.';
        var_dump($user->errors()); // Outputs validation errors
    }

创建自定义解析器方法

为了增强灵活性和满足特定的验证需求,我们的库允许用户定义自定义解析方法。本节展示了如何创建一个size解析方法,该方法验证数组的长度、字符串的长度或数字的值是否符合特定要求。

size方法检查以下内容:

  • 数组的长度等于指定的尺寸。
  • 字符串的长度等于指定的字符数。
  • 数字值正好等于指定的数字。

以下是实现此自定义解析方法的步骤

    use function Zec\z;
    use function Zec\bundler;
    use Zec\FIELD as FK;

    $custom_size_parser = parser_build()
        ->name('size')
        ->prioritize('string', 'number', 'array') // Prioritize the parser for string, number, and array types
        ->argument('message', 'Invalid size', function (Zec\Zec $z) {
            return $z->required()->string();
        }) // argument for custom message, default is 'Invalid size'
        ->argument('size', 0, function (Zec\Zec $z) {
            return $z->required()->number();
        }) // argument for size, default is 0
        ->function(function (array $args): string|bool {
            $value = $args['value'];
            $expected_size = $args['size'];
            $message = $args['message'];

            if (is_array($value)) {
                $actual_size = count($value);
            } elseif (is_string($value)) {
                $actual_size = strlen($value);
            } elseif (is_numeric($value)) {
                $actual_size = $value;
            } else {
                return $message ?? 'Invalid data type';
            }

            if ($actual_size === $expected_size) {
                return true;
            }
            return $message ?? 'Invalid size';
        })->priority(4); // priority of the parser, the default priority of parser is 10, parser with 5 as priority will override before parser with 10 as priority if they have the same parser name
        ->build(); // Build the parser

    bundler->addParser($custom_size_parser);

您现在可以在模式定义中使用自定义的size解析方法了

    $my_schema = z()->options([
        'username' => z()->string()->size(5), // Username must be a string of length 5
        'favorite_numbers' => z()->array()->size(5), // Favorite numbers must be an array of length 5
        'lucky_number' => z()->number()->size(5), // Lucky number must be 5
    ]);

    $user_data = [
        'username' => 'admin',
        'favorite_numbers' => [1, 2, 3, 4, 5],
        'lucky_number' => 5
    ]; // Valid data

    $parsed_data = $my_schema->parse($user_data); // Returns a Zec object

    // Validate the parsed data
    if ($parsed_data->isValid()) { // Returns true if data is valid
        echo 'All data is valid.';
    } else {
        echo 'Data validation failed. Errors: ';
        var_dump($parsed_data->errors()); // Outputs validation errors
    }

许可

本项目采用MIT许可证 - 有关详细信息,请参阅LICENSE.md文件。

MIT许可证

版权所有 © 2024 Mohamed Amine SAYAGH

保留所有权利。

在此特此授予任何获得此软件及其相关文档副本(“软件”)的个人免费使用该软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许软件的提供者为此目的使用该软件,但需遵守以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何形式的保证,明示或暗示,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论是在合同行为、侵权行为或其他行为中产生的,与软件或其使用或其他交易有关。