Skip to content

Serialization

Learn how to serialize DTOs to arrays, JSON, XML, and other formats.

Serialization converts DTOs to different formats for storage or transmission:

$dto = new UserDTO(name: 'John Doe', email: 'john@example.com');
// To array
$array = $dto->toArray();
// To JSON
$json = json_encode($dto);
// To XML
$xml = $dto->toXml();
$dto = UserDTO::fromArray([
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => 30,
]);
$array = $dto->toArray();
// ['name' => 'John Doe', 'email' => 'john@example.com', 'age' => 30]
$dto = UserDTO::fromArray([
'name' => 'John Doe',
'address' => [
'street' => '123 Main St',
'city' => 'New York',
],
]);
$array = $dto->toArray();
// [
// 'name' => 'John Doe',
// 'address' => [
// 'street' => '123 Main St',
// 'city' => 'New York',
// ],
// ]
$dto = new UserDTO(name: 'John Doe', email: 'john@example.com');
$json = json_encode($dto);
// {"name":"John Doe","email":"john@example.com"}
$json = json_encode($dto, JSON_PRETTY_PRINT);
// {
// "name": "John Doe",
// "email": "john@example.com"
// }
$json = $dto->toJson();
// {"name":"John Doe","email":"john@example.com"}
$json = $dto->toJson(JSON_PRETTY_PRINT);
// Pretty printed JSON
$dto = new UserDTO(name: 'John Doe', email: 'john@example.com');
$xml = $dto->toXml();
// <?xml version="1.0"?>
// <user>
// <name>John Doe</name>
// <email>john@example.com</email>
// </user>
$xml = $dto->toXml(rootElement: 'customer');
// <?xml version="1.0"?>
// <customer>
// <name>John Doe</name>
// <email>john@example.com</email>
// </customer>
$dto = new UserDTO(name: 'John Doe', email: 'john@example.com');
$yaml = $dto->toYaml();
// name: John Doe
// email: john@example.com
$dto = new UserDTO(name: 'John Doe', email: 'john@example.com');
$csv = $dto->toCsv();
// "name","email"
// "John Doe","john@example.com"
$users = UserDTO::collection($userArray);
$csv = $users->toCsv();
class UserDTO extends SimpleDTO
{
public function __construct(
public readonly string $name,
#[WhenAuth]
public readonly ?string $email = null,
#[WhenCan('view-admin')]
public readonly ?array $adminData = null,
) {}
}
// Only includes properties based on conditions
$array = $dto->toArray();
class UserDTO extends SimpleDTO
{
public function __construct(
public readonly string $name,
#[Hidden]
public readonly string $password,
) {}
}
$array = $dto->toArray();
// ['name' => 'John Doe']
// password is excluded
class UserDTO extends SimpleDTO
{
public function __construct(
public readonly string $firstName,
public readonly string $lastName,
) {}
public function toArray(): array
{
return [
'full_name' => $this->firstName . ' ' . $this->lastName,
];
}
}
class UserDTO extends SimpleDTO
{
public function toCustomFormat(): array
{
return [
'user' => [
'name' => $this->name,
'contact' => [
'email' => $this->email,
],
],
];
}
}
// ✅ Good - use appropriate format
$json = $dto->toJson(); // For APIs
$xml = $dto->toXml(); // For XML APIs
$csv = $dto->toCsv(); // For exports
// ✅ Good - hide sensitive data
#[Hidden]
public readonly string $password;
// ❌ Bad - expose sensitive data
public readonly string $password;
// ✅ Good - conditional serialization
#[WhenAuth]
public readonly ?string $email;
// ❌ Bad - always include
public readonly string $email;

The following working examples demonstrate this feature:

All examples are fully tested and can be run directly.

The functionality is thoroughly tested. Key test files:

Run the tests:

Terminal window
# Run tests
task test:unit -- --filter=Serialization