本项目是从 webman-tech/components-monorepo 自动 split 出来的,请勿直接修改
webman 数据传输对象(DTO)组件,提供一套完整的数据处理解决方案,包括数据验证、类型转换、请求处理、响应生成等功能。
该组件通过属性注解和反射机制,实现了自动化的数据处理流程,解决了手动处理数据时容易出错、代码重复等问题。
- 自动数据验证:基于属性注解的验证规则,支持多种验证类型
- 类型自动转换:支持基本类型、枚举、日期时间、嵌套对象等类型的自动转换
- 请求数据处理:从 HTTP 请求中自动提取和处理数据
- 响应数据生成:将对象转换为数组或 HTTP 响应
- 配置数据处理:专门处理应用配置数据
- 灵活的序列化控制:通过注解控制对象到数组的转换行为
- 丰富的属性注解:提供多种内置注解满足不同场景需求
- 代码生成工具:提供基于 Web 的界面,可从 JSON 数据自动生成 DTO 类
composer require webman-tech/dto<?php
use WebmanTech\DTO\BaseDTO;
use WebmanTech\DTO\Attributes\ValidationRules;
class UserDTO extends BaseDTO
{
#[ValidationRules(required: true, string: true, maxLength: 50)]
public string $name;
#[ValidationRules(integer: true, min: 0, max: 150)]
public int $age;
#[ValidationRules(enum: UserStatus::class)]
public UserStatus $status;
}``php // 从数组创建 DTO 实例 $userDTO = UserDTO::fromData([ 'name' => 'John', 'age' => 30, 'status' => UserStatus::Active ]);
// 转换为数组 $userData = $userDTO->toArray();
## 核心组件
### BaseDTO 基础数据传输对象
[BaseDTO](src/BaseDTO.php) 是所有 DTO 的基类,提供核心功能:
- `fromData()`: 从数组创建 DTO 实例
- `toArray()`: 将 DTO 转换为数组
- 数据验证和类型转换
- 支持自定义验证规则
### BaseRequestDTO 请求数据传输对象
[BaseRequestDTO](src/BaseRequestDTO.php) 用于处理 HTTP 请求数据:
- `fromRequest()`: 从 HTTP 请求创建 DTO 实例
- 支持多种请求数据来源(Query、Form、JSON 等)
- 自动提取请求数据
### BaseResponseDTO 响应数据传输对象
[BaseResponseDTO](src/BaseResponseDTO.php) 用于生成 HTTP 响应:
- `toResponse()`: 生成 HTTP 响应
- 支持自定义响应头和状态码
- 可配置响应格式
### BaseConfigDTO 配置数据传输对象
[BaseConfigDTO](src/BaseConfigDTO.php) 用于处理应用配置:
- `fromConfig()`: 从配置创建 DTO 实例
- 支持配置合并和默认值
- 适用于复杂的配置场景
## 属性注解
### ValidationRules 验证规则
[ValidationRules](src/Attributes/ValidationRules.php) 是核心的验证注解,支持多种验证选项:
```php
use WebmanTech\DTO\Attributes\ValidationRules;
class ExampleDTO extends BaseDTO
{
// 基本类型验证
#[ValidationRules(required: true, string: true)]
public string $name;
// 数值验证
#[ValidationRules(integer: true, min: 1, max: 100)]
public int $age;
// 枚举验证
#[ValidationRules(enum: StatusEnum::class)]
public StatusEnum $status;
// 数组验证
#[ValidationRules(array: true, arrayItem: ItemDTO::class)]
public array $items;
// 嵌套对象验证
#[ValidationRules(object: AddressDTO::class)]
public AddressDTO $address;
// 自定义规则
#[ValidationRules(rules: 'email|unique:users')]
public string $email;
}
ToArrayConfig 用于控制 DTO 转换为数组的行为:
use WebmanTech\DTO\Attributes\ToArrayConfig;
#[ToArrayConfig(
only: ['name', 'age'], // 仅包含指定字段
exclude: ['password'], // 排除指定字段
ignoreNull: true, // 忽略空值
emptyArrayAsObject: ['items'], // 空数组转为空对象
singleKey: 'name', // 将单个 key 的值作为 toArray 的结果
)]
class UserResponseDTO extends BaseResponseDTO
{
public string $name;
public int $age;
public ?string $password = null;
public array $items = [];
}提醒:可以在 toArray 时传递 ToArrayConfig 作为参数(注意此时会覆盖类上定义的配置)
用于指定请求中属性的数据来源:
- RequestPropertyInQuery: Query 参数
- RequestPropertyInForm: Form 数据
- RequestPropertyInJson: JSON 数据
- RequestPropertyInHeader: Header 数据
- RequestPropertyInCookie: Cookie 数据
use WebmanTech\DTO\Attributes\RequestPropertyInQuery;
use WebmanTech\DTO\Attributes\RequestPropertyInHeader;
class ApiRequestDTO extends BaseRequestDTO
{
#[RequestPropertyInQuery]
public string $page;
#[RequestPropertyInHeader(name: 'X-API-Token')]
public string $apiToken;
}DTO 组件提供强大的数据验证功能:
class UserCreateDTO extends BaseDTO
{
#[ValidationRules(minLength: 2, maxLength: 50)]
public string $name;
#[ValidationRules(min: 18, max: 100)]
public int $age;
#[ValidationRules(rules: 'email')]
public string $email;
#[ValidationRules(enum: UserRole::class)]
public UserRole $role;
// 自定义验证规则
protected static function getExtraValidationRules(): array
{
return [
'email' => 'unique:users,email'
];
}
// 自定义错误消息
protected static function getValidationRuleMessages(): array
{
return [
'name.required' => '姓名不能为空',
'age.min' => '年龄不能小于18岁'
];
}
}注意:DTO 会自动根据当前属性的类型和是否有默认值来设置必填和数据类型验证
支持多种类型的自动转换:
use WebmanTech\DTO\BaseDTO;
class ProductDTO extends BaseDTO
{
// 基本类型转换
public int $id;
// 枚举类型转换
public ProductStatus $status;
// 日期时间转换
public DateTime $createdAt;
// 嵌套对象转换
public CategoryDTO $category;
// 数组项转换
#[ValidationRules(arrayItem: TagDTO::class)]
public array $tags;
}从 HTTP 请求中自动提取数据:
use WebmanTech\DTO\BaseRequestDTO;
class UserCreateRequest extends BaseRequestDTO
{
#[RequestPropertyInJson(required: true)]
public string $name;
#[RequestPropertyInJson]
public int $age = 0;
#[RequestPropertyInHeader(name: 'X-Request-ID')]
public string $requestId;
}
// 在控制器中使用
public function create(Request $request)
{
$dto = UserCreateRequest::fromRequest($request);
// 处理业务逻辑
}生成结构化的响应数据:
use WebmanTech\DTO\BaseResponseDTO;
class UserResponse extends BaseResponseDTO
{
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly int $age,
) {}
}
// 在控制器中使用
public function show(int $id)
{
$user = User::find($id);
$response = new UserResponse($user->id, $user->name, $user->age);
return $response->toResponse();
}处理应用配置数据:
use WebmanTech\DTO\BaseConfigDTO;
class DatabaseConfig extends BaseConfigDTO
{
public function __construct(
public string $host = 'localhost',
public int $port = 3306,
public string $database = 'test',
public array $options = [],
) {}
}
// 使用配置
$config = DatabaseConfig::fromConfig(config('database'));注意:为了性能和出错的可能性考虑,fromConfig 默认是不校验传参的数据的
仓库提供了一个前端版本的 DTO 代码生成器,构建产物位于 web/index.html,特点如下:
- 基于 Vue + CodeMirror,输入 JSON/JSON5 即可预览生成的 PHP DTO 代码
- 支持 Base DTO 与 Form DTO 两种模式,可复制或下载生成结果
- 允许通过 URL 查询参数或
window.__DTO_GENERATOR_CONFIG动态配置默认生成类型、DTO 命名空间等 - 所有资源均被内联,
index.html+favicon.svg即可离线使用,也方便在 PHP 路由中用file_get_contents读取后输出
快速使用:
- 进入仓库根目录的
web - 双击
index.html或部署到任意 Web 服务器 - 输入 JSON 数据和类名,点击“生成 DTO”即可复制或下载
若要在不同项目中自定义默认参数,可在输出的 HTML 中注入脚本:
<script>
window.__DTO_GENERATOR_CONFIG = {
defaultGenerationType: 'form',
defaultNamespace: 'App\\Admin'
};
</script>更详细的开发与构建流程见 webapp/apps/dto-generator/README.md。
可以通过重写 getExtraValidationRules 方法添加自定义验证规则:
use WebmanTech\DTO\BaseRequestDTO;
class CustomDTO extends BaseRequestDTO
{
#[ValidationRules(required: true)]
public string $field;
protected static function getExtraValidationRules(): array
{
return [
'field' => 'unique:users,field'
];
}
}通过重写 getValidationRuleMessages 方法自定义错误消息:
use WebmanTech\DTO\BaseRequestDTO;
class CustomDTO extends BaseRequestDTO
{
protected static function getValidationRuleMessages(): array
{
return [
'field.required' => '自定义错误消息'
];
}
}通过重写 getValidationRuleCustomAttributes 方法自定义属性名称:
use WebmanTech\DTO\BaseRequestDTO;
class CustomDTO extends BaseRequestDTO
{
protected static function getValidationRuleCustomAttributes(): array
{
return [
'field' => '字段名称'
];
}
}- 合理使用验证规则:根据业务需求选择合适的验证规则
- 类型安全:充分利用 PHP 的类型系统
- 枚举使用:对于固定选项的字段使用枚举类型
- 嵌套对象:合理设计嵌套对象结构
- 性能考虑:对于大量数据处理,注意性能优化
- 错误处理:妥善处理验证失败和转换异常
- 文档注释:为 DTO 属性添加清晰的文档注释
- 使用代码生成器:对于复杂数据结构,可使用
web/index.html快速生成初始 DTO 代码