philiprehberger/php-dto-mapper

Map arrays and JSON to strongly-typed DTOs with attribute-driven configuration

Maintainers

Package info

github.com/philiprehberger/php-dto-mapper

pkg:composer/philiprehberger/php-dto-mapper

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.3 2026-03-17 20:06 UTC

This package is auto-updated.

Last update: 2026-03-17 20:07:16 UTC


README

Tests Latest Version on Packagist License

Map arrays and JSON to strongly-typed DTOs with attribute-driven configuration.

Requirements

Dependency Version
PHP ^8.2

Zero external dependencies.

Installation

composer require philiprehberger/php-dto-mapper

Usage

Define a DTO

use PhilipRehberger\DtoMapper\Attributes\MapFrom;
use PhilipRehberger\DtoMapper\Attributes\Optional;
use PhilipRehberger\DtoMapper\Attributes\CastWith;
use PhilipRehberger\DtoMapper\Casters\DateTimeCaster;

class UserDto
{
    public function __construct(
        public readonly string $name,
        #[MapFrom('email_address')]
        public readonly string $email,
        #[Optional]
        public readonly ?string $nickname = null,
        #[CastWith(DateTimeCaster::class)]
        public readonly ?\DateTimeImmutable $createdAt = null,
    ) {}
}

Map from array

use PhilipRehberger\DtoMapper\DtoMapper;

$dto = DtoMapper::map([
    'name' => 'John',
    'email_address' => 'john@example.com',
    'createdAt' => '2026-01-15 10:30:00',
], UserDto::class);

$dto->name;      // 'John'
$dto->email;     // 'john@example.com'
$dto->createdAt; // DateTimeImmutable

Map from JSON

$dto = DtoMapper::mapJson('{"name": "Jane", "email_address": "jane@example.com"}', UserDto::class);

Map a collection

$dtos = DtoMapper::mapCollection([
    ['name' => 'Alice', 'email_address' => 'alice@example.com'],
    ['name' => 'Bob', 'email_address' => 'bob@example.com'],
], UserDto::class);

Safe mapping

$dto = DtoMapper::tryMap($data, UserDto::class); // Returns null on failure

Nested DTOs

class AddressDto
{
    public function __construct(
        public readonly string $street,
        public readonly string $city,
    ) {}
}

class PersonDto
{
    public function __construct(
        public readonly string $name,
        public readonly AddressDto $address,
    ) {}
}

$dto = DtoMapper::map([
    'name' => 'Alice',
    'address' => ['street' => '123 Main St', 'city' => 'Springfield'],
], PersonDto::class);

$dto->address->city; // 'Springfield'

Custom casters

Implement the Caster interface:

use PhilipRehberger\DtoMapper\Contracts\Caster;

class MoneyFromCentsCaster implements Caster
{
    public function cast(mixed $value): float
    {
        return (int) $value / 100;
    }
}

Use with the #[CastWith] attribute:

class OrderDto
{
    public function __construct(
        #[CastWith(MoneyFromCentsCaster::class)]
        public readonly float $total,
    ) {}
}

Enum casting

use PhilipRehberger\DtoMapper\Attributes\CastWith;
use PhilipRehberger\DtoMapper\Casters\EnumCaster;

enum Status: string
{
    case Active = 'active';
    case Inactive = 'inactive';
}

class AccountDto
{
    public function __construct(
        public readonly string $name,
        #[CastWith(EnumCaster::class, args: [Status::class])]
        public readonly Status $status,
    ) {}
}

API

Method Description
DtoMapper::map(array $data, string $class): object Map an associative array to a DTO
DtoMapper::mapJson(string $json, string $class): object Map a JSON string to a DTO
DtoMapper::mapCollection(array $items, string $class): array Map an array of arrays to DTOs
DtoMapper::tryMap(array $data, string $class): ?object Map returning null on failure

Attributes

Attribute Target Description
#[MapFrom('key')] Property Map from a different source key
#[Optional] Property Allow missing keys, use default value
#[CastWith(Caster::class)] Property Apply a custom caster

Built-in Casters

Caster Description
DateTimeCaster Casts string to DateTimeImmutable
EnumCaster Casts string/int to a backed enum

Development

composer install
vendor/bin/phpunit
vendor/bin/pint --test
vendor/bin/phpstan analyse

License

MIT