PHP code example of tangwei / dto

1. Go to this page and download the library: Download tangwei/dto library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tangwei / dto example snippets


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;
}

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,
        ];
    }
}

use Hyperf\DTO\Annotation\Contracts\RequestBody;

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

use Hyperf\DTO\Annotation\Contracts\RequestQuery;

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

use Hyperf\DTO\Annotation\Contracts\RequestFormData;

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

use Hyperf\DTO\Annotation\Contracts\RequestHeader;

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

#[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 参数
}

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'];
    }
}

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;
}

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;
}

namespace App\Request;

use Hyperf\DTO\Annotation\ArrayType;

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

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

    // 使用 ArrayType 注解显式指定类型(优先级高于 @var)
    #[ArrayType(User::class)]
    public array $members;

    // 简单类型也可以使用 PhpType 枚举
    #[ArrayType(\Hyperf\DTO\Type\PhpType::INT)]
    public array $scores;
}

/**
 * @param User[] $users
 */
#[PostMapping(path: 'batch')]
public function batch(#[RequestBody] #[Valid] array $users): array
{
    // $users 为 User[],每个元素都已验证并映射
}

enum Status: int
{
    case ACTIVE = 1;
    case DISABLED = 0;
}

class UserRequest
{
    public Status $status; // 请求传 1 时自动映射为 Status::ACTIVE
}

namespace App\Request;

use Hyperf\DTO\Annotation\JSONField;

class ApiRequest
{
    // 将请求中的 user_name 映射到 userName,响应序列化时也输出 user_name
    #[JSONField('user_name')]
    public string $userName;

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

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;
}

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

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

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

use Hyperf\DTO\Annotation\Validation\Validation;

class ComplexRequest
{
    // 使用管道符分隔多个规则
    #[Validation('

namespace App\Validation;

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

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

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

use App\Validation\Phone;
use Hyperf\DTO\Annotation\Validation\Required;

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



use Hyperf\DTO\Type\Convert;

return [
    // 是否启用扫描缓存(生产环境建议 true,配合部署流程预生成代理文件)
    'scan_cacheable' => false,

    // DTO 代理文件生成目录
    'proxy_dir' => BASE_PATH . '/runtime/container/proxy/',

    // 属性默认值级别:
    // 0 - 不注入默认值(jsonSerialize 时用 ?? 默认值兜底,推荐)
    // 1 - 为简单类型属性注入默认值(int=0、string=''、array=[]、bool=false)
    // 2 - 在 1 的基础上,将类类型属性也改为可空并默认 null
    'dto_default_value_level' => 0,

    // 全局响应字段名转换(camel / studly / snake / none / custom)
    'responses_global_convert' => Convert::SNAKE,
];

use Hyperf\DTO\Mapper;

// 数组/对象 → DTO
$user = Mapper::map(['name' => 'tom', 'age' => 20], new User());

// 数组 → DTO 数组
$users = Mapper::mapArray($list, User::class);

// 对象间属性复制(支持 Arrayable 模型)
Mapper::copyProperties($model, new UserResponse());

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

#[Dto(responseConvert: Convert::SNAKE)]
class UserResponse
{
    public string $userName; // 序列化输出 user_name
    public int $loginCount;  // 序列化输出 login_count
}

use Hyperf\DTO\Type\ConvertCustom;

ConvertCustom::setClosure(fn (string $name) => 'prefix_' . $name);

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

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

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

namespace App\Exception\Handler;

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

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;
    }
}

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

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