codebot / phpdto
用于生成 PHP 数据传输对象的 CLI 工具。
Requires
- php: >=8.0
- ext-json: *
- codebot/phpenum: ^0.1.2
Requires (Dev)
- phpunit/phpunit: ^8.2
README
关于
用于生成 PHP 数据传输对象的 CLI 工具。
此实用程序可以基于 JSON 模式生成 PHP 8 DTO 类。
安装
使用 composer 安装此包
composer require --dev codebot/phpdto 0.3.*
请注意,此包所需的最低 PHP 版本是 8.0。
初始化
vendor/bin/phpdto init
当前工作目录是从您调用 phpdto
命令的目录。
此命令将初始化 phpdto 并在您的当前工作目录中创建 phpdto.json 配置文件和 phpdto_patterns 目录。
配置
phpdto.json 配置文件包含以下变量
PHP_DTO_PATTERNS_DIR - 用于存储 DTO 的 JSON 模式的目录。
PHP_DTO_NAMESPACE - 生成 DTO 类的命名空间。
PHP_DTO_CLASS_POSTFIX - DTO 类的后缀,例如 Item(没有后缀),ItemDto(后缀是 "Dto")。
这些变量存储为环境变量。
使用方法
要生成 DTO 类,您必须创建一个模式,它是一个包含有关生成类信息的 JSON 文件。
DTO JSON 模式
DTO 模式的示例
{ "class": "item", "namespace_postfix": "", "props": { "id": "int", "count": "?int", "name": "string", "description": "?string", "is_active": "bool" } }
class
将结合 phpdto.json
配置文件中指定的 PHP_DTO_CLASS_POSTFIX 的类名。
因此,如果类名是 item
,并且类后缀配置值是 Dto
,则生成的类名将是 ItemDto
。
namespace_postfix
将结合 phpdto.json
配置文件中指定的 PHP_DTO_NAMESPACE 的生成 DTO 类命名空间后缀。
因此,如果命名空间后缀是 \User
,并且默认 DTO 命名空间是 App\Dto
,则生成的类命名空间将是 App\Dto\User
。
您可以留空命名空间后缀。
props
此对象包含有关 DTO 类属性和方法的信息。键将被转换为类属性。值包含有关获取器返回类型的信息。
"description" : "?string"
- 由于此对,将添加 $_description
属性到 DTO 类,其中包含 private ?string $_description
属性和 getDescription(): ?string
方法,该方法期望返回类型 "string" 并允许 null。
生成 DTO
假设您已经在 phpdto_patterns
文件夹中创建了一个名为 item.json
的模式。
运行 vendor/bin/phpdto -f=item
以生成 DTO 类。它将存储在 phpdto.json
配置文件中指定的命名空间下,结合模式中指定的命名空间后缀。
假设您正在从 "DTO JSON 模式" 部分中显示的模式生成 DTO 类,那么您将生成以下类。
<?php namespace App\Dto; use PhpDto\Dto; use PhpDto\DtoSerialize; use PhpDto\ToArray; class ItemDto extends Dto { use DtoSerialize, ToArray; private int $_id; private ?int $_count; private string $_name; private ?string $_description; private bool $_isActive; public function __construct( array $item ) { $this->_id = $item['id']; $this->_count = $item['count']; $this->_name = $item['name']; $this->_description = $item['description']; $this->_isActive = $item['is_active']; } public function getId(): int { return $this->_id; } public function getCount(): ?int { return $this->_count; } public function getName(): string { return $this->_name; } public function getDescription(): ?string { return $this->_description; } public function getIsActive(): bool { return $this->_isActive; } }
如何使用
有两种映射方法
静态函数 mapArray(array $items, bool $shouldSerialize = false): array
静态函数 mapSingle(array $item, bool $shouldSerialize = false): Dto|stdClass
当您需要映射多维数组时使用 mapArray
,否则使用 mapSingle
。
映射示例
单例
$itemData = [ 'id' => 1, 'name' => 'Dummy Item', 'description' => 'Some dummy description.', 'count' => 10, 'is_active' => true, 'meta' => [ 'meta_title' => 'Dummy meta title', 'meta_description' => 'Dummy meta description', ], 'tags' => 'TagOne, TagTwo, TagThree' ]; $item = ItemDto::mapSingle( $itemData ); // Now you are able to access DTO properties via getters $item->getId(); $item->Name(); $item->getDescription(); $item->getCount(); $item->getIsActive();
多维
$itemData = [ [ 'id' => 1, 'name' => 'Dummy Item', 'description' => 'Some dummy description.', 'count' => 10, 'is_available' => true, 'meta' => [ 'meta_title' => 'Dummy meta title', 'meta_description' => 'Dummy meta description', ], 'tags' => 'TagOne, TagTwo, TagThree' ], // more items ]; $items = ItemDto::mapArray( $itemData ); // array of instance of ItemDto class foreach( $items as $item ) { $item->getId(); // ... }
考虑根据要映射的数组的数据结构重构生成的 DTO 类的构造函数。
有时您可能希望将 DTO 作为对象使用,以便可以将它们传递到 AJAX 响应或其他所需位置。
映射方法的双参数是决定数据是否应序列化的标志。
ItemDto::mapSingle( $itemData, true )
- 这将返回一个序列化对象的 DTO
{
"id": 1
"name": "Dummy Item"
"description": "Some dummy description."
"count": 10
"isActive": true
}
对于 mapArray
方法也是如此。
DTO 模拟器
您可以使用 PhpDto\Services\DtoFaker
类轻松地为您的 DTO 生成假数据。
$fakeData = DtoFaker::fakeSingle( ItemDto::class ); // array that contains fake data for ItemDto $item = ItemDto::mapSingle( $fakeData );
现在您的项目看起来像这样
{
"id": 993
"count": 340
"name": "2R9ifLLxfG965wikJWrr"
"description": "MluADBj2rwmAjBC6ZyH4"
"isActive": false
}
所有值都是随机生成的,甚至是 isActive 字段的布尔值。
您可以通过 DtoFaker::fakeArray
方法伪造多维数组。
以下示例中,我们想要伪造 10 个项目的数据。
$fakeData = DtoFaker::fakeArray( ItemDto::class, 10 ); $items = ItemDto::mapArray( $fakeData );
Dto::fakeArray
方法的第二个参数是生成项目的数量。
Dto::fakeSingle
和 Dto::fakeArray
方法使用 PHP 反射 API 获取关于属性和获取器的信息。
或者,您可以使用 Dto::fakeSingeFromPattern
和 Dto::fakeArrayFromPattern
方法。您必须传递它们完整的 json 模式路径
.Dto::fakeArrayFromPattern('/full/path/to/pattern.json')
ToArray
特性和 toArray(): array
方法。
当您需要将 DTO 对象转换为数组时,可以使用 toArray
方法。
<?php namespace App\Dto; use PhpDto\Dto; use PhpDto\ToArray; class MockDto extends Dto { use ToArray; private ?string $_name; private int $_count; private bool $_isTrue; public function __construct( array $data ) { $this->_name = $data['name']; $this->_count = $data['count']; $this->_isTrue = $data['is_true']; } public function getName(): ?string { return $this->_name; } public function getCount(): int { return $this->_count; } public function getIsTrue(): bool { return $this->_isTrue; } } $mockData = [ 'name' => 'Mock name', 'count' => 4, 'is_true' => true ]; $dto = new MockDto($mockData); $arr = $dto->toArray(); var_dump($arr);
输出将如下所示
array(3) {
'name' =>
string(9) "Mock name"
'count' =>
int(4)
'is_true' =>
bool(true)
}
toArray
方法接受两个参数:toSnakeCase
和 includeNulls
如果您想保持数组键的格式与类字段相同,可以传递 toSnakeCase: false
参数:$arr = $dto->toArray(toSnakeCase: false);
如果您想包含具有 null
值的键,可以传递 includeNulls: true
参数:$arr = $dto->toArray(includeNulls: true);
输出将是
array(3) {
'name' =>
string(9) "Mock name"
'count' =>
int(4)
'isTrue' =>
bool(true)
}
所以现在 isTrue
键是驼峰式。