JSON → PHP 8.2+ DTO
Arquitetura PHP moderna

Gerador de DTOs Tipados Readonly em PHP 8.2+ a partir de JSON

Converta dados JSON em DTOs modernos com readonly classes do PHP 8.2+, promoção de construtor e desserializadores fromArray.

Predefinições
Payload JSON de OrigemVálido
<?php

declare(strict_types=1);

namespace App\DTO;

/**
 * @param string[] $tags
 */
final readonly class UserDto implements \JsonSerializable
{
    public function __construct(
        public string $id,
        public string $email,
        public string $username,
        public string $displayName,
        public string $role,
        public bool $isActive,
        public TenantDto $tenant,
        public PreferencesDto $preferences,
        /** @var string[] */
        public array $tags = [],
        public \DateTimeImmutable $lastLoginAt,
        public \DateTimeImmutable $createdAt,
    ) {}

    public static function fromArray(array $data): self
    {
        return new self(
            id: (string) ($data['id'] ?? $data['id'] ?? null ?? ''),
            email: (string) ($data['email'] ?? $data['email'] ?? null ?? ''),
            username: (string) ($data['username'] ?? $data['username'] ?? null ?? ''),
            displayName: (string) ($data['display_name'] ?? $data['displayName'] ?? null ?? ''),
            role: (string) ($data['role'] ?? $data['role'] ?? null ?? ''),
            isActive: (bool) ($data['is_active'] ?? $data['isActive'] ?? null ?? false),
            tenant: TenantDto::fromArray((array) ($data['tenant'] ?? [])),
            preferences: PreferencesDto::fromArray((array) ($data['preferences'] ?? [])),
            tags: array_map(fn($item) => (string) $item, (array) ($data['tags'] ?? [])),
            lastLoginAt: isset($data['last_login_at']) ? new \DateTimeImmutable((string) $data['last_login_at']) : null,
            createdAt: isset($data['created_at']) ? new \DateTimeImmutable((string) $data['created_at']) : null,
        );
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'email' => $this->email,
            'username' => $this->username,
            'display_name' => $this->displayName,
            'role' => $this->role,
            'is_active' => $this->isActive,
            'tenant' => $this->tenant->toArray(),
            'preferences' => $this->preferences->toArray(),
            'tags' => $this->tags,
            'last_login_at' => $this->lastLoginAt?->format(\DateTimeInterface::ATOM),
            'created_at' => $this->createdAt?->format(\DateTimeInterface::ATOM),
        ];
    }

    public function jsonSerialize(): array
    {
        return $this->toArray();
    }
}

final readonly class TenantDto implements \JsonSerializable
{
    public function __construct(
        public string $id,
        public string $name,
        public string $tier,
        public int $activeSeats,
        public string $billingContact,
    ) {}

    public static function fromArray(array $data): self
    {
        return new self(
            id: (string) ($data['id'] ?? $data['id'] ?? null ?? ''),
            name: (string) ($data['name'] ?? $data['name'] ?? null ?? ''),
            tier: (string) ($data['tier'] ?? $data['tier'] ?? null ?? ''),
            activeSeats: (int) ($data['active_seats'] ?? $data['activeSeats'] ?? null ?? 0),
            billingContact: (string) ($data['billing_contact'] ?? $data['billingContact'] ?? null ?? ''),
        );
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'tier' => $this->tier,
            'active_seats' => $this->activeSeats,
            'billing_contact' => $this->billingContact,
        ];
    }

    public function jsonSerialize(): array
    {
        return $this->toArray();
    }
}

final readonly class PreferencesDto implements \JsonSerializable
{
    public function __construct(
        public string $theme,
        public bool $notificationsEnabled,
        public string $locale,
        public string $timezone,
    ) {}

    public static function fromArray(array $data): self
    {
        return new self(
            theme: (string) ($data['theme'] ?? $data['theme'] ?? null ?? ''),
            notificationsEnabled: (bool) ($data['notifications_enabled'] ?? $data['notificationsEnabled'] ?? null ?? false),
            locale: (string) ($data['locale'] ?? $data['locale'] ?? null ?? ''),
            timezone: (string) ($data['timezone'] ?? $data['timezone'] ?? null ?? ''),
        );
    }

    public function toArray(): array
    {
        return [
            'theme' => $this->theme,
            'notifications_enabled' => $this->notificationsEnabled,
            'locale' => $this->locale,
            'timezone' => $this->timezone,
        ];
    }

    public function jsonSerialize(): array
    {
        return $this->toArray();
    }
}
3 Classes
Classes DTO Geradas
20 Campos
Propriedades Tipadas
0 ms de atraso do servidor
Motor PHP 8.2+ Readonly

Readonly Classes do PHP 8.2+ & Promoção de Construtor

Utilize classes readonly modernas do PHP 8.2 com promoção de propriedades no construtor e imutabilidade profunda para máxima segurança de tipos.

Garantia de Privacidade 100% no Cliente

Todo o processamento JSON e geração de código PHP acontecem exclusivamente na memória do seu navegador sem transmissão para servidores externos.

Serialização e Desserialização Bidirecional

Gera métodos estáticos fromArray() com hidratação recursiva de DTOs filhos, além de toArray() e interface JsonSerializable.

Referência técnica e guia de arquitetura

Guia do Desenvolvedor: Gerador de DTOs Tipados Readonly em PHP 8.2+ a partir de JSON — Guia de referência

Converta dados JSON em DTOs modernos com readonly classes do PHP 8.2+, promoção de construtor e desserializadores fromArray.

Parâmetros principais e controles

Root Class NameString (Identificador PHP)

Identificador da classe de nível superior gerada para o objeto JSON raiz.

Padrão: RootDto
NamespaceString (Namespace PHP)

Declaração de namespace compatível com PSR-4 adicionada aos arquivos DTO gerados.

Padrão: App\DTO
PHP Target VersionEnum ('8.2+', '8.1', '8.0')

Sintaxe da versão do PHP; 8.2+ gera readonly classes com promoção de propriedades no construtor.

Padrão: 8.2+
Constructor PromotionBoolean

Declara e inicializa propriedades tipadas diretamente na lista de argumentos do __construct().

Padrão: true
Deserializer Hydration (fromArray)Boolean

Gera um método estático tipado fromArray(array $data): self com mapeamento recursivo de DTOs filhos.

Padrão: true
Property CasingEnum ('camelCase', 'snake_case', 'preserve')

Normaliza chaves JSON para identificadores camelCase idiomáticos do PHP mantendo o mapeamento de origem.

Padrão: camelCase
DateTime DetectionBoolean

Detecta strings no padrão ISO 8601 e as tipifica automaticamente como propriedades \DateTimeImmutable.

Padrão: true

Dicas profissionais e melhores práticas

Hidratação Recursiva de DTOs Filhos

Ao converter estruturas JSON aninhadas ou listas de sub-objetos, utilize array_map() no fromArray() para acionar os hidratadores estáticos dos DTOs filhos com segurança contra valores nulos.

No PHP 8.2+

No PHP 8.2+, declarar readonly class aplica o modificador readonly a todas as propriedades de instância, impedindo mutações acidentais e implementando semântica estrita de Value Object.

Arrays Heterogêneos e Tipos de União

Para coleções JSON com valores nulos ou escalares variados, use tipos de união do PHP 8.0+ (como string|int|null) e blocos PHPDoc (/** @var list<UserDto> */) para garantir conformidade estática total no PHPStan e Psalm (Nível 8+).`

Associe a promoção de construtor a

Associe a promoção de construtor a atributos como Symfony #[SerializedName('chave')] ou Spatie #[MapInputName] para separar completamente os contratos de APIs externas dos modelos internos da aplicação.

Problemas comuns e solução de problemas

Erro fatal 'Cannot modify readonly property' em tempo de execução

Propriedades readonly no PHP 8.2 não podem ser modificadas após o término do construtor. Adote métodos imutáveis de clonagem (withers) ou passe todos os valores necessários durante a chamada do fromArray().

Falha ao desempacotar array associativo aninhado no construtor

Nunca envie arrays associativos brutos diretamente para parâmetros tipados de classes filhas; realize o mapeamento através do método estático fromArray() correspondente.

Exceção DateMalformedStringException na conversão de datas no PHP 8.3+

Valide a string de data antes de chamar new \DateTimeImmutable() ou envolva a criação em bloco try-catch para atribuir fallback nulo ?\DateTimeImmutable quando a data for opcional ou inválida.

Perguntas frequentes (FAQ)

Quais as principais vantagens de usar readonly classes do PHP 8.2 em DTOs?▼

Elas bloqueiam qualquer alteração de estado após a instanciação e proíbem a criação de propriedades dinâmicas. Isso assegura imutabilidade completa, segurança concorrente em ambientes assíncronos (como Swoole e RoadRunner) e elimina a sobrecarga de cópias defensivas.

De que forma a promoção de construtor elimina código repetitivo (boilerplate)?▼

Em vez de declarar propriedades na classe, recebê-las no construtor e efetuar a atribuição manual ($this->prop = $prop), a promoção unifica visibilidade, tipo e valor padrão em uma única assinatura de __construct(), enxugando o código em mais de 60%.

É possível gerar DTOs compatíveis com Symfony Serializer ou Spatie Laravel Data?▼

Sim. O gerador permite ativar atributos nativos como #[SerializedName] do Symfony e #[MapInputName] do Spatie Data, integrando payloads JSON em snake_case com propriedades de objetos em camelCase sem atrito.

Como o método fromArray() lida com campos ausentes ou nulos?▼

O gerador avalia todas as amostras do JSON para detectar chaves ausentes ou nulas, configurando tipos anuláveis (?string $campo = null) e o operador de coalescência nula ($data['campo'] ?? null) para extinguir avisos de chaves indefinidas.

O payload JSON informado é transmitido para algum servidor remoto?▼

Não. Todo o parsing de JSON, dedução de tipos em árvore AST e geração de código PHP acontecem exclusivamente na memória do seu navegador através de JavaScript do cliente, garantindo 100% de sigilo e privacidade.

Ferramentas e utilitários relacionados

Todas as ferramentas →