dldash / data-transfer-object

数据传输对象。

1.0.0 2020-12-31 11:51 UTC

This package is auto-updated.

Last update: 2024-08-29 05:54:10 UTC


README

Latest Version License Total Downloads Build

⚡️ 要求

  • 🐘 PHP >= 8.0

💥 安装

composer require dldash/data-transfer-object

✨ 使用

简单 DTO

如果传递了 DTO 类中未描述的额外字段,它们将被忽略。

DTO 类

use Dldash\DataTransferObject\Models\DataTransferObject;

class UserDto extends DataTransferObject
{
    public function __construct(
        public int $userId,
        public string|null $username
    ) {}
}

使用

$request = [
    'userId' => 100,
    'username' => 'admin',
    'emailAddress' => 'admin@test.com'
];

$dto = UserDto::create($request);

值对象

您还可以在 DTO 类中使用值对象。
您需要做的就是实现 ValueObjectContract 接口。

值对象类

use Dldash\DataTransferObject\Contracts\ValueObjectContract;

class EmailAddress implements ValueObjectContract, JsonSerializable
{
    public function __construct(private string $value)
    {
        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException("Email address [${value}] is not valid.");
        }

        $this->value = strtolower($value);
    }

    public function value(): string
    {
        return $this->value;
    }

    public function jsonSerialize(): string
    {
        return $this->value;
    }
}

DTO 类

use Dldash\DataTransferObject\Models\DataTransferObject;

class OrderDto extends DataTransferObject
{
    public function __construct(
        public int $orderId,
        public EmailAddress $emailAddress
    ) {}
}

使用

$request = [
    'orderId' => 100,
    'emailAddress' => 'admin@test.com'
];

$dto = OrderDto::create($request);

嵌套 DTO 类

DTO 类

use Dldash\DataTransferObject\Models\DataTransferObject;

class OrderDto extends DataTransferObject
{
    public function __construct(
        public int $orderId,
        public UserDto $user
    ) {}
}

使用

$request = [
    'orderId' => 100,
    'user' => [
        'userId' => 100,
        'username' => 'admin'
    ]
];

$dto = OrderDto::create($request);

类型化 DTO 数组和集合

您可以使用 DTO 对象的数组。
为此,您需要继承抽象的 DataTransferObjectCollection 类。

集合类

use Dldash\DataTransferObject\Objects\DataTransferObjectCollection;

/** @method ArrayIterator|UserDto[] getIterator() */
class UserDtoCollection extends DataTransferObjectCollection
{
    protected function create(mixed $item): object
    {
        return UserDto::create($item);
    }
}

DTO 类

use Dldash\DataTransferObject\Models\DataTransferObject;

class OrderDto extends DataTransferObject
{
    public function __construct(
        public int $orderId,
        public UserDtoCollection $users
    ) {}
}

使用

$request = [
    'orderId' => 100,
    'users' => [
        [
            'userId' => 100,
            'username' => 'admin'
        ],
        [
            'userId' => 200,
            'username' => null
        ]
    ]
];

$dto = OrderDto::create($request);

部分更新

让我们假设我们需要更新某些模型,但希望进行部分更新。在这种情况下,不是所有必需的字段都可以传递给 DTO 类。您可以将 Undefined 类型添加到所需字段。

注意:如果传递一个 null 值,它也将是 null

DTO 类

use Dldash\DataTransferObject\Objects\Undefined;
use Dldash\DataTransferObject\Models\DataTransferObject;

class OrderDto extends DataTransferObject
{
    public function __construct(
        public int $orderId,
        public string|null|Undefined $name
    ) {}
}

使用

use Dldash\DataTransferObject\Objects\Undefined;

$request = [
    'orderId' => 100
];

$dto = OrderDto::create($request);

if (Undefined::isPresent($dto->name)) {
    // Update this field
}

序列化名称

DTO 类

use Dldash\DataTransferObject\Attributes\SerializedName;
use Dldash\DataTransferObject\Models\DataTransferObject;

class OrderDto extends DataTransferObject
{
    public function __construct(
        #[SerializedName('order_id')]
        public int $id,

        #[SerializedName('order_name')]
        public string $name
    ) {}
}

使用

$request = [
    'order_id' => 100,
    'order_name' => 'Order'
];

$dto = OrderDto::create($request);

echo $dto->id; // 100
echo $dto->name; // Order
echo json_encode($dto); // {"order_id": 100, "order_name": "Order"}

💫 测试

composer test