Dto

Création d'objets à partir d'array et vice-versa

Depuis PHP 8.2, c'est devenu un vrai bonheur de coder des Dtos, des entities, des Value Object, ... car le code peut être beaucoup moins verbeux et beaucoup plus strict.

Exemple de Value Object immutable :

final readonly class Coordinate
{
    public function __construct(
        public float $latitude,
        public float $longitude,
    ) {
    }
}

// Instantiation "magique" depuis un array.
$coord = Coordinate(...['latitude' => 1.5, 'longitude' => 40.5]);

Exemple d'entity avec sous object auto-construit :

enum Gender
{
    case Male;
    case Female;
    case Other;
}

final readonly class User
{
    public function __construct(
        public int $id,
        public string $name,
        public null|Gender $gender = null,
        public DateTimeImmutable $createdAt = new DateTimeImmutable(),
    ) {
    }
}

// Pas besoin de renseigner $createdAt : il sera auto instantié (new en default).
$user = new User(1, 'Arnaud');

Besoin

Pour plusieurs projets perso, j'ai besoin de consommer des Apis JSON, à chaque fois, les phases de validation (Json-schema, manuel, ...) à base d'array etc ... sont très consommatrices de temps et fastitieuses.

Mon idée, c'est de créer des structures complètes d'objets modernes, immutables si possible, à partir du json de ces apis : cela fait de facto office de validation et me permet d'utiliser des objets propres, auto-documentés, etc ...

Il existe déjà pas mal de lib qui savent faire plus ou moins ce genre de choses, je pense par exemple à symfony/serializer.

symfony/serializer schema
Ma lib en gros c'est le denormalize/normalize (en vert)

Quel est mon problème avec ces libs ?

Mon besoin

Exemple :

$converter = new \Arnapou\Dto\DtoConverter();

$object = $converter->fromdata($array, MaClasse::class);
$array = $converter->toData($object);

La lib fournit de base un DtoConverter "tout en un" qui est suffisant pour démarrer.
Ce dernier sait gérer de base :

Vous pouvez implementer vous-même vos DataConverter et gérer vos objets particuliers. C'est très ouvert.

Détails

Pour plus de détails techniques, allez voir le README sur Gitlab.

Liens