maduser/argon-dto

A PHP package for Data Transfer Objects (DTOs)

v1.0.0 2025-07-27 06:51 UTC

This package is auto-updated.

Last update: 2025-07-27 10:23:27 UTC


README

PHP Build codecov Psalm Level Code Style Latest Version License: MIT

Argon DTO

A lightweight PHP DTO implementation with support for array and JSON hydration, serialization, and optional auto-mapping using field constants. Reflection at runtime is avoided by design.

Requirements

  • PHP 8.2+
  • Composer

Installation

composer require maduser/argon-dto

Overview

This package provides:

  • A base AbstractDTO class for immutable data transfer objects.
  • Optional auto-mapping via AutoMappableInterface and AutoMap.
  • Consistent serialization via toArray() and toJson().
  • Custom exceptions for misconfiguration or serialization errors.

Usage

Simple DTO

For a basic DTO, just extend AbstractDTO:

use Maduser\Argon\DTO\AbstractDTO;

final class ProductDTO extends AbstractDTO
{
    public function __construct(
        public readonly int $id,
        public readonly string $name
    ) {}
}

$dto = new ProductDTO(1, 'Gadget');

Auto-Mapping DTO

If you want array-to-constructor mapping without manually unpacking arrays:

use Maduser\Argon\DTO\AbstractDTO;
use Maduser\Argon\DTO\Contracts\AutoMappableInterface;
use Maduser\Argon\DTO\Traits\AutoMap;

final class UserDTO extends AbstractDTO implements AutoMappableInterface
{
    use AutoMap;

    public const MAPPABLE_FIELDS = ['id', 'name'];

    public function __construct(
        public readonly int $id,
        public readonly string $name
    ) {}
}

You can then hydrate from arrays or JSON:

$dto = UserDTO::fromArray(['id' => 1, 'name' => 'Alice']);
$dto = UserDTO::fromJson('{"id":1,"name":"Alice"}');

Accessing Data

$array = $dto->toArray();
$json = $dto->toJson();

Mapping Logic

If your DTO implements AutoMappableInterface, you must define a mapFromArray() method. You can implement this manually or use the provided AutoMap trait. The trait uses MAPPABLE_FIELDS to determine which keys to extract from the input array and in what order:

public static function mapFromArray(array $data): array
{
    $fqcn = static::class;

    if (!defined("$fqcn::MAPPABLE_FIELDS")) {
        throw DTOMappingException::missingMap($fqcn);
    }

    /** @var list<string> $fields */
    $fields = constant("$fqcn::MAPPABLE_FIELDS");

    return array_map(
        static function (string $key) use ($data, $fqcn): mixed {
            if (!array_key_exists($key, $data)) {
                throw DTOMappingException::missingField($key, $fqcn);
            }
            return $data[$key];
        },
        $fields
    );
}
  • The order of keys in the input array is irrelevant.
  • Extra keys in the input array are ignored.

Error Handling

  • DTOConfigurationException – DTO lacks required mapping behavior.
  • DTOMappingException – Missing fields or invalid MAPPABLE_FIELDS.
  • DTOSerializationException – JSON encoding/decoding failures.

Testing

vendor/bin/phpunit
vendor/bin/psalm
vendor/bin/phpcs

License

MIT