PHPackages                             tangwei/dto - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. tangwei/dto

ActiveLibrary

tangwei/dto
===========

php hyperf dto

v3.1.7(3mo ago)21131.5k—8.6%9[1 issues](https://github.com/tw2066/dto/issues)2MITPHPPHP &gt;=8.1CI passing

Since Jun 29Pushed 1mo ago2 watchersCompare

[ Source](https://github.com/tw2066/dto)[ Packagist](https://packagist.org/packages/tangwei/dto)[ RSS](/packages/tangwei-dto/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (12)Versions (58)Used By (2)

Hyperf DTO
==========

[](#hyperf-dto)

[![Latest Stable Version](https://camo.githubusercontent.com/2b522ee0636df7f80fe22c5372a1aab64f7c26d901117a1e25991d4c225669ab/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74616e677765692f64746f)](https://packagist.org/packages/tangwei/dto)[![Total Downloads](https://camo.githubusercontent.com/8e42d378c91b0fb08cced5bfe670d28d150c792db288a8426a67327fbf317c91/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f74616e677765692f64746f)](https://packagist.org/packages/tangwei/dto)[![License](https://camo.githubusercontent.com/3054d1db09e585ab675f3ce56fe8bd1d8c71326bed86a3a4261c2b7c7840c2fa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f74616e677765692f64746f)](https://github.com/tw2066/dto)[![PHP Version](https://camo.githubusercontent.com/6518db1335bf20fdff07253dc6d6d0cec955b5fb6a8ef1382ac6d73687ecc07f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d626c7565)](https://www.php.net)

[English](./README_EN.md) | 中文

基于 [Hyperf](https://github.com/hyperf/hyperf) 框架的 DTO (数据传输对象) 映射和验证库，使用 PHP 8.1+ 的属性（Attributes）特性，提供优雅的请求参数绑定和验证方案。

✨ 特性
----

[](#-特性)

- 🚀 **自动映射** - 请求参数自动映射到 PHP DTO 类
- 🎯 **类型安全** - 利用 PHP 8.1+ 的类型系统，提供完整的类型提示
- 🔄 **递归支持** - 支持数组、嵌套对象、递归结构
- ✅ **数据验证** - 集成 Hyperf 验证器，提供丰富的验证注解
- 📝 **多种参数源** - 支持 Body、Query、FormData、Header 等多种参数来源
- 🎨 **代码优雅** - 基于 PHP 8 Attributes，代码简洁易读
- 🔧 **易于扩展** - 支持自定义验证规则和类型转换

📋 环境要求
------

[](#-环境要求)

- PHP &gt;= 8.1
- Hyperf

📦 安装
----

[](#-安装)

```
composer require tangwei/dto
```

安装后，组件会自动注册，无需额外配置。

📖 快速开始
------

[](#-快速开始)

### 基本使用

[](#基本使用)

#### 1. 创建 DTO 类

[](#1-创建-dto-类)

```
namespace App\Request;

use Hyperf\DTO\Annotation\Validation\Required;
use Hyperf\DTO\Annotation\Validation\Integer;
use Hyperf\DTO\Annotation\Validation\Between;

class DemoQuery
{
    public string $name;

    #[Required]
    #[Integer]
    #[Between(1, 100)]
    public int $age;
}
```

#### 2. 在控制器中使用

[](#2-在控制器中使用)

```
namespace App\Controller;

use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\DTO\Annotation\Contracts\RequestQuery;
use Hyperf\DTO\Annotation\Contracts\Valid;
use App\Request\DemoQuery;

#[Controller(prefix: '/user')]
class UserController
{
    #[GetMapping(path: 'info')]
    public function info(#[RequestQuery] #[Valid] DemoQuery $request): array
    {
        return [
            'name' => $request->name,
            'age' => $request->age,
        ];
    }
}
```

📚 注解说明
------

[](#-注解说明)

### 参数来源注解

[](#参数来源注解)

> 命名空间：`Hyperf\DTO\Annotation\Contracts`

#### RequestBody

[](#requestbody)

获取 POST/PUT/PATCH 请求的 Body 参数

```
use Hyperf\DTO\Annotation\Contracts\RequestBody;

#[PostMapping(path: 'create')]
public function create(#[RequestBody] CreateUserRequest $request)
{
    // $request 会自动填充 Body 中的数据
}
```

#### RequestQuery

[](#requestquery)

获取 URL 查询参数（GET 参数）

```
use Hyperf\DTO\Annotation\Contracts\RequestQuery;

#[GetMapping(path: 'list')]
public function list(#[RequestQuery] QueryRequest $request)
{
    // $request 会自动填充 Query 参数
}
```

#### RequestFormData

[](#requestformdata)

获取表单请求数据（Content-Type: multipart/form-data）

```
use Hyperf\DTO\Annotation\Contracts\RequestFormData;

#[PostMapping(path: 'upload')]
public function upload(#[RequestFormData] UploadRequest $formData)
{
    // $formData 会自动填充表单数据
    // 文件上传需要通过 $this->request->file('field_name') 获取
}
```

#### RequestHeader

[](#requestheader)

获取请求头信息

```
use Hyperf\DTO\Annotation\Contracts\RequestHeader;

#[GetMapping(path: 'info')]
public function info(#[RequestHeader] HeaderRequest $headers)
{
    // $headers 会自动填充请求头数据
}
```

#### Valid

[](#valid)

启用验证，必须与其他参数来源注解一起使用

```
#[PostMapping(path: 'create')]
public function create(#[RequestBody] #[Valid] CreateUserRequest $request)
{
    // 请求参数会先验证，验证失败会自动抛出异常
}
```

### 组合使用

[](#组合使用)

可以在同一方法中组合使用多种参数来源：

```
#[PutMapping(path: 'update/{id}')]
public function update(
    int $id,
    #[RequestBody] #[Valid] UpdateRequest $body,
    #[RequestQuery] QueryRequest $query,
    #[RequestHeader] HeaderRequest $headers
) {
    // 同时获取 Body、Query 和 Header 参数
}
```

> ⚠️ **注意**：同一个方法不能同时使用 `RequestBody` 和 `RequestFormData` 注解

📝 完整示例
------

[](#-完整示例)

### 控制器示例

[](#控制器示例)

```
namespace App\Controller;

use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Hyperf\DTO\Annotation\Contracts\RequestBody;
use Hyperf\DTO\Annotation\Contracts\RequestQuery;
use Hyperf\DTO\Annotation\Contracts\RequestFormData;
use Hyperf\DTO\Annotation\Contracts\Valid;

#[Controller(prefix: '/demo')]
class DemoController
{
    #[GetMapping(path: 'query')]
    public function query(#[RequestQuery] #[Valid] DemoQuery $request): array
    {
        return [
            'name' => $request->name,
            'age' => $request->age,
        ];
    }

    #[PostMapping(path: 'create')]
    public function create(#[RequestBody] #[Valid] CreateRequest $request): array
    {
        // 处理创建逻辑
        return ['id' => 1, 'message' => 'Created successfully'];
    }

    #[PutMapping(path: 'update')]
    public function update(
        #[RequestBody] #[Valid] UpdateRequest $body,
        #[RequestQuery] QueryParams $query
    ): array {
        // 同时使用 Body 和 Query 参数
        return ['message' => 'Updated successfully'];
    }

    #[PostMapping(path: 'upload')]
    public function upload(#[RequestFormData] UploadRequest $formData): array
    {
        $file = $this->request->file('photo');
        // 处理文件上传
        return ['message' => 'Uploaded successfully'];
    }
}
```

### DTO 类示例

[](#dto-类示例)

#### 简单 DTO

[](#简单-dto)

```
namespace App\Request;

use Hyperf\DTO\Annotation\Validation\Required;
use Hyperf\DTO\Annotation\Validation\Integer;
use Hyperf\DTO\Annotation\Validation\Between;
use Hyperf\DTO\Annotation\Validation\Email;

class CreateRequest
{
    #[Required]
    public string $name;

    #[Required]
    #[Email]
    public string $email;

    #[Required]
    #[Integer]
    #[Between(18, 100)]
    public int $age;
}
```

#### 嵌套对象 DTO

[](#嵌套对象-dto)

```
namespace App\Request;

class UserRequest
{
    public string $name;

    public int $age;

    // 嵌套对象
    public Address $address;
}

class Address
{
    public string $province;

    public string $city;

    public string $street;
}
```

#### 数组类型 DTO

[](#数组类型-dto)

```
namespace App\Request;

use Hyperf\DTO\Annotation\ArrayType;

class BatchRequest
{
    /**
     * @var int[]
     */
    public array $ids;

    /**
     * @var User[]
     */
    public array $users;

    // 使用 ArrayType 注解显式指定类型
    #[ArrayType(User::class)]
    public array $members;
}
```

#### 自定义字段名

[](#自定义字段名)

```
namespace App\Request;

use Hyperf\DTO\Annotation\JSONField;

class ApiRequest
{
    // 将请求中的 user_name 映射到 userName
    #[JSONField('user_name')]
    public string $userName;

    #[JSONField('user_age')]
    public int $userAge;
}
```

✅ 数据验证
------

[](#-数据验证)

### 内置验证注解

[](#内置验证注解)

> 需要先安装 Hyperf 验证器：`composer require hyperf/validation`

本库提供了丰富的验证注解，包括：

- `Required` - 必填项
- `Integer` - 整数
- `Numeric` - 数字
- `Between` - 范围验证
- `Min` / `Max` - 最小/最大值
- `Email` - 邮箱格式
- `Url` - URL 格式
- `Date` - 日期格式
- `DateFormat` - 指定日期格式
- `Boolean` - 布尔值
- `Alpha` - 字母
- `AlphaNum` - 字母和数字
- `AlphaDash` - 字母、数字、破折号、下划线
- `Image` - 图片文件
- `Json` - JSON 格式
- `Nullable` - 可为空
- `In` - 在指定值中
- `NotIn` - 不在指定值中
- `Regex` - 正则表达式
- `Unique` - 数据库唯一
- `Exists` - 数据库存在

### 使用示例

[](#使用示例)

#### 基本验证

[](#基本验证)

```
use Hyperf\DTO\Annotation\Validation\Required;
use Hyperf\DTO\Annotation\Validation\Integer;
use Hyperf\DTO\Annotation\Validation\Between;

class DemoQuery
{
    #[Required]
    public string $name;

    #[Required]
    #[Integer]
    #[Between(1, 100)]
    public int $age;
}
```

在控制器中使用 `#[Valid]` 注解启用验证：

```
#[GetMapping(path: 'query')]
public function query(#[RequestQuery] #[Valid] DemoQuery $request)
{
    // 参数已经验证通过
}
```

#### 自定义错误消息

[](#自定义错误消息)

```
class UserRequest
{
    #[Required("用户名不能为空”)]
    public string $name;

    #[Between(18, 100, "年龄必须在 18-100 之间")]
    public int $age;
}
```

#### 使用 Validation 注解

[](#使用-validation-注解)

`Validation` 注解支持 Laravel 风格的验证规则：

```
use Hyperf\DTO\Annotation\Validation\Validation;

class ComplexRequest
{
    // 使用管道符分隔多个规则
    #[Validation("required|string|min:3|max:50”)]
    public string $username;

    // 数组元素验证
    #[Validation("integer”, customKey: 'ids.*')]
    public array $ids;
}
```

### 自定义验证规则

[](#自定义验证规则)

继承 `BaseValidation` 类即可创建自定义验证规则：

```
namespace App\Validation;

use Attribute;
use Hyperf\DTO\Annotation\Validation\BaseValidation;

#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
class Phone extends BaseValidation
{
    protected $rule = 'regex:/^1[3-9]\\d{9}$/';

    public function __construct(string $messages = '手机号格式不正确')
    {
        parent::__construct($messages);
    }
}
```

使用自定义验证：

```
use App\Validation\Phone;

class RegisterRequest
{
    #[Required]
    #[Phone]
    public string $mobile;
}
```

🔧 高级功能
------

[](#-高级功能)

### RPC 支持

[](#rpc-支持)

在 JSON-RPC 服务中返回 PHP 对象，需要配置序列化支持。

#### 1. 安装依赖

[](#1-安装依赖)

```
composer require symfony/serializer ^5.0|^6.0
composer require symfony/property-access ^5.0|^6.0
```

#### 2. 配置 Aspect

[](#2-配置-aspect)

在 `config/autoload/aspects.php` 中添加：

```
return [
    \Hyperf\DTO\Aspect\ObjectNormalizerAspect::class,
];
```

#### 3. 配置依赖

[](#3-配置依赖)

在 `config/autoload/dependencies.php` 中添加：

```
use Hyperf\Serializer\SerializerFactory;
use Hyperf\Serializer\Serializer;

return [
    Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```

### 自定义类型转换

[](#自定义类型转换)

如果需要自定义类型转换逻辑，可以实现自己的转换器：

```
namespace App\Convert;

use Hyperf\DTO\Type\ConvertCustom;

class CustomConvert implements ConvertCustom
{
    public function convert(mixed $value): mixed
    {
        // 自定义转换逻辑
        return $value;
    }
}
```

在 DTO 类中使用：

```
use Hyperf\DTO\Annotation\Dto;
use Hyperf\DTO\Type\Convert;

#[Dto(Convert::SNAKE)]
class UserResponse
{
    public string $name;
    public int $age;
}
```

💡 最佳实践
------

[](#-最佳实践)

### 1. DTO 类结构设计

[](#1-dto-类结构设计)

- 为不同的请求类型创建独立的 DTO 类
- 使用有意义的类名，如 `CreateUserRequest`、`UpdateUserRequest`
- 将 Request DTO 和 Response DTO 分开存放

### 2. 验证规则

[](#2-验证规则)

- 优先使用内置验证注解，保持代码可读性
- 复杂验证使用 `Validation` 注解
- 通用验证规则封装为自定义注解

### 3. 错误处理

[](#3-错误处理)

验证失败会抛出 `Hyperf\Validation\ValidationException` 异常，可以通过异常处理器统一处理：

```
namespace App\Exception\Handler;

use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\Validation\ValidationException;
use Psr\Http\Message\ResponseInterface;
use Hyperf\HttpMessage\Stream\SwooleStream;

class ValidationExceptionHandler extends ExceptionHandler
{
    public function handle(\Throwable $throwable, ResponseInterface $response)
    {
        if ($throwable instanceof ValidationException) {
            $this->stopPropagation();
            return $response->withStatus(422)->withBody(
                new SwooleStream(json_encode([
                    'code' => 422,
                    'message' => 'Validation failed',
                    'errors' => $throwable->validator->errors()->toArray(),
                ]))
            );
        }
        return $response;
    }

    public function isValid(\Throwable $throwable): bool
    {
        return $throwable instanceof ValidationException;
    }
}
```

📚 常见问题
------

[](#-常见问题)

### Q: 为什么验证没有生效？

[](#q-为什么验证没有生效)

A: 请确保：

1. 已安装 `hyperf/validation` 组件
2. 在控制器方法参数上添加了 `#[Valid]` 注解
3. DTO 类中的属性添加了验证注解

### Q: 如何处理嵌套数组？

[](#q-如何处理嵌套数组)

A: 使用 PHPDoc 或 `ArrayType` 注解：

```
/**
 * @var User[]
 */
public array $users;

// 或者
#[ArrayType(User::class)]
public array $users;
```

### Q: 可以同时使用 RequestBody 和 RequestFormData 吗？

[](#q-可以同时使用-requestbody-和-requestformdata-吗)

A: 不可以。这两个注解是互斥的，因为它们处理不同的请求类型。

### Q: 如何处理文件上传？

[](#q-如何处理文件上传)

A: 使用 `RequestFormData` 注解，然后通过 `$this->request->file()` 获取文件。

🔗 相关链接
------

[](#-相关链接)

- [Hyperf 官方文档](https://hyperf.wiki)
- [Hyperf Validation](https://hyperf.wiki/3.1/#/zh-cn/validation)
- [PHP Attributes](https://www.php.net/manual/zh/language.attributes.php)

###  Health Score

59

—

FairBetter than 99% of packages

Maintenance85

Actively maintained with recent releases

Popularity43

Moderate usage in the ecosystem

Community15

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~31 days

Recently: every ~37 days

Total

52

Last Release

77d ago

Major Versions

v0.3.0 → v1.0.02021-10-28

v1.0.3 → 2.0.x-dev2022-03-10

v2.1.9 → v3.0.0-beta12023-08-17

v2.1.10 → v3.0.0-beta42023-08-28

v2.1.11 → v3.0.22023-12-12

PHP version history (2 changes)v0.1.0PHP &gt;=8.0

v3.0.0-beta1PHP &gt;=8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/24579418?v=4)[Mr.tang](/maintainers/tw2066)[@tw2066](https://github.com/tw2066)

---

Top Contributors

[![tw2066](https://avatars.githubusercontent.com/u/24579418?v=4)](https://github.com/tw2066 "tw2066 (192 commits)")

---

Tags

dtohyperfhyperf dtohyperf swagger

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tangwei-dto/health.svg)

```
[![Health](https://phpackages.com/badges/tangwei-dto/health.svg)](https://phpackages.com/packages/tangwei-dto)
```

###  Alternatives

[mineadmin/mineadmin

Quickly build a background management system for web applications

1.2k2.0k](/packages/mineadmin-mineadmin)[friendsofhyperf/validated-dto

The Data Transfer Objects with validation for Hyperf.

1412.9k](/packages/friendsofhyperf-validated-dto)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
