- 🐘 PHP >= 8.0
composer require dldash/data-transfer-object- 👉 Simple DTO
- 👉 Value Objects
- 👉 Nested DTO classes
- 👉 Typed DTO arrays and collections
- 👉 Partial update
- 👉 Serialized name
If extra fields are passed that are not described in the DTO class, they will be ignored.
DTO class:
useDldash\DataTransferObject\Models\DataTransferObject;
class UserDto extends DataTransferObject
{
publicfunction__construct(
publicint$userId,
publicstring|null$username
) {}
}Usage:
$request = [
'userId' => 100,
'username' => 'admin',
'emailAddress' => 'admin@test.com'
];
$dto = UserDto::create($request);You can also use value objects in DTO classes.
All you need is to implement the ValueObjectContract interface.
Value object class:
useDldash\DataTransferObject\Contracts\ValueObjectContract;
class EmailAddress implements ValueObjectContract, JsonSerializable
{
publicfunction__construct(privatestring$value)
{
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
thrownewInvalidArgumentException("Email address [${value}] is not valid.");
}
$this->value = strtolower($value);
}
publicfunctionvalue(): string
{
return$this->value;
}
publicfunctionjsonSerialize(): string
{
return$this->value;
}
}DTO class:
useDldash\DataTransferObject\Models\DataTransferObject;
class OrderDto extends DataTransferObject
{
publicfunction__construct(
publicint$orderId,
publicEmailAddress$emailAddress
) {}
}Usage:
$request = [
'orderId' => 100,
'emailAddress' => 'admin@test.com'
];
$dto = OrderDto::create($request);DTO class:
useDldash\DataTransferObject\Models\DataTransferObject;
class OrderDto extends DataTransferObject
{
publicfunction__construct(
publicint$orderId,
publicUserDto$user
) {}
}Usage:
$request = [
'orderId' => 100,
'user' => [
'userId' => 100,
'username' => 'admin'
]
];
$dto = OrderDto::create($request);You can use arrays of DTO objects.
To do this, you need to inherit the abstract DataTransferObjectCollection class.
Collection class:
useDldash\DataTransferObject\Objects\DataTransferObjectCollection;
/** @method ArrayIterator|UserDto[] getIterator() */class UserDtoCollection extends DataTransferObjectCollection
{
protectedfunctioncreate(mixed$item): object
{
return UserDto::create($item);
}
}DTO class:
useDldash\DataTransferObject\Models\DataTransferObject;
class OrderDto extends DataTransferObject
{
publicfunction__construct(
publicint$orderId,
publicUserDtoCollection$users
) {}
}Usage:
$request = [
'orderId' => 100,
'users' => [
[
'userId' => 100,
'username' => 'admin'
],
[
'userId' => 200,
'username' => null
]
]
];
$dto = OrderDto::create($request);Let's imagine that we need to update some model, but we want to do a partial update.
In this case, not all the required fields can be passed to the DTO class.
You can add the Undefined type to the desired field.
NOTE: If you pass a null value, it will also be null.
DTO class:
useDldash\DataTransferObject\Objects\Undefined;
useDldash\DataTransferObject\Models\DataTransferObject;
class OrderDto extends DataTransferObject
{
publicfunction__construct(
publicint$orderId,
publicstring|null|Undefined$name
) {}
}Usage:
useDldash\DataTransferObject\Objects\Undefined;
$request = [
'orderId' => 100
];
$dto = OrderDto::create($request);
if (Undefined::isPresent($dto->name)) {
// Update this field
}DTO class:
useDldash\DataTransferObject\Attributes\SerializedName;
useDldash\DataTransferObject\Models\DataTransferObject;
class OrderDto extends DataTransferObject
{
publicfunction__construct(
#[SerializedName('order_id')]
publicint$id,
#[SerializedName('order_name')]
publicstring$name
) {}
}Usage:
$request = [
'order_id' => 100,
'order_name' => 'Order'
];
$dto = OrderDto::create($request);
echo$dto->id; // 100echo$dto->name; // Orderechojson_encode($dto); // {"order_id": 100, "order_name": "Order"}composer test