klkvsk/dto-generator

使用零运行时依赖生成 DTO 类

0.6.6 2023-04-18 13:20 UTC

This package is auto-updated.

Last update: 2024-09-18 18:17:42 UTC


README

Latest Version on Packagist GitHub GitHub last commit GitHub Repo stars

使用零运行时依赖生成 DTO 类

此包允许您通过简短的 PHP 代码声明模式来生成干净、独立的 DTO 类(也称为 "值对象")。

安装

您只需要在开发环境中使用此包,因为生成的类不使用此库的任何代码。这就是为什么首选的方式是将它包含在 require-dev 中。

$ composer require --dev klkvsk/dto-generator

要求

  • PHP 8.1+:在开发中运行生成器
  • PHP 7.4 或 8.x:在生产中使用生成的代码

用法

1. 创建模式文件

模式是一个常规 PHP 文件,位于项目中的任何位置。该文件应从顶层返回一个 Schema 对象。

示例模式

<?php
use Klkvsk\DtoGenerator\Schema as dto;
use Klkvsk\DtoGenerator\Schema\Types as t;

return dto\schema(
    namespace: 'MyProject\Data',
    objects: [
        new dto\object(
            name: 'Person',
            fields: [
                dto\field('name', t\string(), required: true),
                dto\field('age', t\int(), required: true),
            ]
        ),
    ]
);

2. 生成文件

使用 dto-gen 命令进行代码生成

$ ./vendor/bin/dto-gen [schema-file]

默认情况下,生成器会搜索名为或以 dto.schema.php 结尾的文件,但您可以通过参数手动提供模式文件。

生成器会尝试通过查看 composer.json 中的自动加载路径来猜测正确的输出路径。如果它声明了 "MyProject\\": "src/" 的 PSR-4 映射,那么上面的文件将放置在 src/Data/Person.php

要覆盖此行为,您可以直接指定 outputDir

dto\schema(namespace: "MyProject\\Data", outputDir: "src/generated/", ...);

特性

向后兼容

要生成针对某些 PHP 最小版本的代码,请使用

./vendor/bin/dto-gen --target 7.4

此选项启用或禁用结果代码中的一些较新语言功能。

枚举

您不仅可以生成 DTO,还可以生成相关的枚举

dto\schema(
    objects: [
        dto\enum(
            name: 'PostStatus'
            cases: [ 'draft', 'published', 'deleted' ]
        ),
        dto\object(
            name: 'Post',
            fields: [
                dto\field('status', t\enum('PostStatus'), required: true),
                ...
            ]
        )
    ]
)

对于 PHP >= 8.0,将生成原生枚举,对于旧版本,将使用非常类似类实现的类。

类型系统

DTO 用于保持数据类型的安全。模式的类型有

  • t\intt\boolt\stringt\float - 基本标量类型
  • t\enumt\object - 用于引用其他 DTO 对象
  • t\date - 使用 DateTimeImmutable
  • t\external - 用于引用任何其他非 DTO 类
  • t\list_(T) - 将类型 T 包装起来以声明 T[]
  • t\mixed - 如果您真的不知道

(其中 tKlkvsk\DtoGenerator\Schema\Types 的别名)

此外,您可以根据需要扩展抽象 Type 类。

填充和验证

DTO 可以使用常规构造函数或使用 <DTO>::create(array $data) 方法创建。

create 方法接受一个包含数据的关联数组。然后,该数据被 过滤(如果需要事先进行一些清理)并 导入(转换为适当的类型)。之后,该方法调用默认构造函数,并将导入的字段传递给它。构造函数不仅通过类型,还通过自定义逻辑来 验证 字段。

因此,数据操作有三个阶段,每个阶段都可以在模式中使用可调用函数进行描述

  1. filter 准备要导入的数据
  2. importer 将值转换为正确的类型或实例化嵌套对象
  3. validator 检查导入的值是否符合指定的标准

filterimporter 闭包应返回处理过的值。如果返回 null,则不会调用其他闭包。

validator 返回 true/false,如果返回 false,则自动抛出 InvalidArgumentException。您还可以抛出自定义异常而不返回任何内容。

filtervalidator 类型的闭包在模式中定义

dto\field('age', t\int(),
    filters: [ fn ($x) => preg_replace('/[^0-9]+/', $x) ],
    validators: [ fn ($x) => $x > 0 && $x < 100 ]
)

importer 闭包对所有类型都预定义,除了 t\object

dto\field('file', t\external(SplFileInfo::class, fn ($x) => new SplFileInfo($x))

如果您为自定义需要扩展 Type,则可以指定自定义导入器。

示例

请参阅 /example/ 目录以获取示例架构和不同PHP版本的生成类。

许可证

MIT许可证(MIT)。有关更多信息,请参阅 许可证文件