Installation:
composer require bigyohann/symfony-dto-bundle
Add to config/bundles.php:
return [
// ...
Bigyohann\DtoBundle\BigyohannDtoBundle::class => ['all' => true],
];
First DTO Class:
Extend Bigyohann\DtoBundle\Dto\Dto and define private properties with getters:
use Bigyohann\DtoBundle\Dto\Dto;
class UserDto extends Dto {
private ?string $name;
public function getName(): ?string { return $this->name; }
}
First Use Case: Convert an array to DTO in a controller:
use Bigyohann\DtoBundle\Dto\Dto;
public function show(Request $request, Dto $dto): Response {
$userData = ['name' => 'John'];
$userDto = $dto->convert($userData); // Auto-maps properties
return new Response($userDto->getName());
}
DTO Design:
Dto for auto-conversion or DtoInterface for manual control.#[ConvertProperty] to opt-in/out of auto-mapping.#[ConvertProperty(shouldConvertAutomatically: false)]
private ?int $id;
Controller Integration:
Dto service (auto-registered) or create custom DTOs.$dto = $this->dtoConverter->convert($request->all(), UserDto::class);
Validation:
Leverage Symfony’s constraints (e.g., #[Type], #[Length]) directly on DTO properties.
Service Layer: Use DTOs for API responses or form handling:
public function getUser(User $user): UserDto {
return (new UserDto())->convert($user->toArray());
}
convert() with a subset of properties:
$dto->convert(['name' => 'Jane']); // Only updates `name`
convert() for complex logic:
public function convert(array $data): self {
$this->name = strtoupper($data['name'] ?? '');
return $this;
}
Property Visibility:
private for auto-conversion to work.Attribute Conflicts:
#[ConvertProperty] overrides default behavior. Omit it to disable auto-conversion for a property.Circular References:
UserDto has AddressDto, which has UserDto).Type Safety:
convert(). Validate manually or use Symfony’s #[Type] constraint.convert() method’s input/output.BigyohannDtoBundle is in config/bundles.php and composer.json autoloads the Bigyohann\DtoBundle namespace.Exclude Sensitive Data:
Use shouldConvertAutomatically: false for passwords or tokens:
#[ConvertProperty(shouldConvertAutomatically: false)]
private ?string $apiToken;
Custom Conversion Logic:
Extend Dto and override convert():
public function convert(array $data): self {
$data['name'] = ucfirst($data['name']);
return parent::convert($data);
}
Performance: Reuse DTO instances instead of creating new ones:
$dto = new UserDto();
$dto->convert($data); // Reuse instead of `new UserDto()->convert($data)`
Testing:
Mock Dto in tests to isolate logic:
$dto = $this->createMock(Dto::class);
$dto->method('convert')->willReturn($dto);
How can I help you explore Laravel packages today?