定制 horizom/dto 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

horizom/dto

Composer 安装命令:

composer require horizom/dto

包简介

Data Transfer Objects for all PHP applications

README 文档

README

Horizom DTO

Data Transfer Objects for all PHP applications.

Total Downloads Latest Stable Version License

Data Transfer Objects (DTOs) are objects that are used to transfer data between systems. DTOs are typically used in applications to provide a simple, consistent format for transferring data between different parts of the application, such as between the user interface and the business logic.

Installation

composer require horizom/dto

Usage

Defining DTO Properties

use Horizom\DTO\DTO;

class UserDTO extends DTO
{
    public string $name;

    public string $email;

    public string $password;
}

Creating DTO Instances

You can create a DTO instance on many ways:

From array

$dto = new UserDTO([
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'password' => 's3CreT!@1a2B'
]);

You can also use the fromArray static method:

$dto = UserDTO::fromArray([
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'password' => 's3CreT!@1a2B'
]);

From JSON strings

$dto = UserDTO::fromJson('{"name": "John Doe", "email": "john.doe@example.com", "password": "s3CreT!@1a2B"}');

Accessing DTO Data

After you create your DTO instance, you can access any properties like an object:

$dto = new UserDTO([
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'password' => 's3CreT!@1a2B'
]);

$dto->name; // 'John Doe'
$dto->email; // 'john.doe@example.com'
$dto->password; // 's3CreT!@1a2B'

Casting DTO Properties

You can cast your DTO properties to some types:

use App\Enums\UserRole;
use Carbon\Carbon;
use Horizom\DTO\DTO;
use DateTimeImmutable;
use Horizom\DTO\Casting\ArrayCast;
use Horizom\DTO\Casting\EnumCast;

class UserDTO extends DTO
{
    public string $id;

    public string $name;

    public string $email;

    public string $password;

    public Carbon $created_at;

    public DateTimeImmutable $updated_at;

    public array $roles;

    protected function casts()
    {
        return [
            'id' => 'integer',
            'name' => 'string',
            'email' => 'string',
            'password' => 'string',
            'created_at' => Carbon::class,
            'updated_at' => DateTimeImmutable::class,
            'admin_role' => UserRole::class,
            'roles' => new ArrayCast(new EnumCast(UserRole::class)),
        ];
    }
}

Defining Default Values

Sometimes we can have properties that are optional and that can have default values. You can define the default values for your DTO properties in the defaults function:

use Horizom\DTO\DTO;
use Illuminate\Support\Str;

class UserDTO extends DTO
{
    // ...

    protected function defaults()
    {
        return [
            'username' => Str::slug($this->name),
        ];
    }
}

With the DTO definition above you could run:

$dto = new UserDTO([
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'password' => 's3CreT!@1a2B'
]);

$dto->username; // 'john_doe'

Built-in Cast Types

The following type alias strings are available out of the box in casts():

Alias Class Description
'string' StringCast Casts to string via (string)
'integer' IntegerCast Casts to int; throws on non-numeric input
'boolean' BooleanCast Casts to bool; handles 'true', 'yes', '1', etc.
'double' FloatCast Casts to float; throws on non-numeric input
'array' ArrayCast Casts to array; accepts JSON strings
'object' ObjectCast Casts to stdClass; accepts JSON strings or arrays
'datetime' DateTimeCast Casts to DateTimeImmutable (default format Y-m-d H:i:s, UTC)

For custom formats or timezones, instantiate DateTimeCast directly:

'published_at' => new DateTimeCast('d/m/Y', 'Europe/Paris'),

Transforming DTO Data

You can convert your DTO to some formats:

To array

Cast property values are automatically reversed (uncasted) to scalars: enums → their backing value, DateTimeInterface → formatted string, nested DTOs → recursive array.

$dto = new UserDTO([
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'password' => 's3CreT!@1a2B',
]);

$dto->toArray();
// [
//     "name" => "John Doe",
//     "email" => "john.doe@example.com",
//     "password" => "s3CreT!@1a2B",
// ]

To JSON string

$dto->toJson();
// '{"name":"John Doe","email":"john.doe@example.com","password":"s3CreT!@1a2B"}'

DTOs can also be cast directly to string — (string) $dto calls toJson() automatically.

Inspecting DTO State

Check if any data is present

$dto->filled(); // true if at least one property is non-null

Access original raw input

$dto->getOriginal();
// Returns the unmodified array originally passed to the constructor or fill()

Re-hydrate an existing instance

$dto->fill(['name' => 'Jane Doe', 'email' => 'jane@example.com']);
// Re-populates the DTO, re-applies casts and defaults

Create Your Own Type Cast

Castable classes

You can easily create new Castable types for your project by implementing the Horizom\DTO\Contracts\CastableContract interface. This interface has a single method that must be implemented:

public function cast(string $property, mixed $value): mixed;

Let's say that you have a URLWrapper class in your project, and you want that when passing a URL into your DTO it will always return a URLWrapper instance instead of a simple string:

use Horizom\DTO\Contracts\CastableContract;

class URLCast implements CastableContract
{
    public function cast(string $property, mixed $value): URLWrapper
    {
        return new URLWrapper($value);
    }
}

Then you could apply this to your DTO:

use Horizom\DTO\DTO;

class CustomDTO extends DTO
{
    protected function casts()
    {
        return [
            'url' => new URLCast(),
        ];
    }

    protected function defaults()
    {
        return [];
    }
}

Callable casts

You can also create new Castable types for your project by using a callable/callback:

use Horizom\DTO\DTO;

class CustomDTO extends DTO
{
    protected function casts(): array
    {
        return [
            'url' => function (string $property, mixed $value) {
                return new URLWrapper($value);
            },
        ];
    }

    protected function defaults(): array
    {
        return [];
    }
}

Or you can use a static method:

use Horizom\DTO\Casting\Cast;
use Horizom\DTO\DTO;

class CustomDTO extends DTO
{
    protected function casts()
    {
        return [
            'url' => Cast::make(
                function (string $property, mixed $value) {
                    return new URLWrapper($value);
                },
                function (string $property, URLWrapper $value) {
                    return $value->toString();
                }
            )
        ];
    }

    protected function defaults()
    {
        return [];
    }
}

Case of possibility of extending with Laravel

You can extend the DTO class to create your own DTO class with some custom methods:

use App\Http\Resources\UserResource;
use Horizom\DTO\DTO;
use Illuminate\Database\Eloquent\Model;

class UserDTO extends DTO
{
    public int $id;

    public string $name;

    public string $email;

    public string $password;

    public Carbon $created_at;

    public CarbonImmutable $updated_at;

    public DateTimeImmutable $verified_at;

    public static function fromModel(Model $model) {
        return new self($model->toArray());
    }

    public function toModel() {
        return new Model($this->toArray());
    }

    public function toResource() {
        return new UserResource($this->toArray());
    }

    protected function casts()
    {
        return [
            'id' => 'integer',
            'name' => 'string',
            'email' => 'string',
            'password' => 'string',
            'created_at' => Carbon::class,
            'updated_at' => CarbonImmutable::class,
            'verified_at' => DateTimeImmutable::class,
        ];
    }
}

License

The MIT License (MIT). Please see License File for more information.

horizom/dto 适用场景与选型建议

horizom/dto 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.82k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2023 年 11 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「dto」 「Data Transfer Object」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 horizom/dto 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 horizom/dto 我们能提供哪些服务?
定制开发 / 二次开发

基于 horizom/dto 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.82k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-11-18