JSON → PHP 8.2+ DTO
モダンPHPアーキテクチャ

JSON to PHP 8.2+ 型付き Readonly DTO ジェネレーター

JSON データをコンストラクタプロモーションと fromArray デシリアライザを備えた最新の PHP 8.2+ readonly class DTO(データ転送オブジェクト)に変換します。

プリセット
入力 JSON ペイロード正常
<?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
推論された DTO クラス
20 フィールド
型付けプロパティ
サーバー遅延 0ms
PHP 8.2+ Readonly エンジン

PHP 8.2+ Readonly クラスとコンストラクタプロモーション

コンストラクタプロパティプロモーション、厳格な型宣言、完全なイミュータビリティを備えた最新の PHP 8.2 readonly クラスを活用します。

完全ローカル・プライバシー保証

すべての JSON 解析、型推論、コード生成はブラウザ内部で 100% 完結します。データが外部サーバーに送信されることは一切ありません。

双方向シリアライズとデシリアライズ

再帰的な子 DTO マッピングを備えた型安全な fromArray() ファクトリメソッドと、toArray() および JsonSerializable を自動生成します。

技術リファレンス&アーキテクチャガイド

JSON to PHP 8.2+ 型付き Readonly DTO ジェネレーター — リファレンスガイド

JSON データをコンストラクタプロモーションと fromArray デシリアライザを備えた最新の PHP 8.2+ readonly class DTO(データ転送オブジェクト)に変換します。

主要パラメータ&設定項目

Root Class Name文字列 (PHP識別子)

ルート JSON オブジェクトに対して生成されるトップレベルの PHP クラス名。

初期値: RootDto
Namespace文字列 (PHP名前空間)

生成される DTO クラスに付与される PSR-4 準拠の PHP 名前空間宣言。

初期値: App\DTO
PHP Target Version列挙型 ('8.2+', '8.1', '8.0')

出力対象の PHP 言語構文。8.2+ では readonly class 宣言とコンストラクタプロモーションを使用します。

初期値: 8.2+
Constructor Promotion真偽値 (Boolean)

__construct() 引数リスト内でプロパティの可視性、型、代入を直接宣言します。

初期値: true
Deserializer Hydration (fromArray)真偽値 (Boolean)

再帰的なネスト DTO マッピングを備えた型安全な静的 fromArray(array $data): self ファクトリメソッドを生成します。

初期値: true
Property Casing列挙型 ('camelCase', 'snake_case', 'preserve')

JSON キーのマッピングを保持しながら、PHP プロパティ識別子を標準的な camelCase に正規化します。

初期値: camelCase
DateTime Detection真偽値 (Boolean)

ISO 8601 形式の日時文字列を自動検出し、\DateTimeImmutable 型プロパティとしてマッピングします。

初期値: true

プロの活用テクニック&推奨設定

再帰的なネスト DTO ハイドレーション

ネストされた JSON 構造や子オブジェクト配列を処理する場合、fromArray() 内で array_map() を活用し、子 DTO の静的ハイドレーターを null 安全に再帰呼び出ししてください。

PHP 8.2 Readonly クラスによる不変性の保証

PHP 8.2 以降では、readonly class を宣言することで全インスタンスプロパティに readonly が暗黙適用され、意図しない値の書き換えを防ぎ完全な値オブジェクト(Value Object)セマンティクスを実現できます。

混合型配列とユニオン型の活用

null や異種スカラー値が混在する JSON 配列では、PHP 8.0+ のユニオン型(string|int|null 等)や PHPDoc アノテーション(/** @var list<UserDto> */)を組み合わせることで、PHPStan や Psalm のレベル 8+ 静的解析を完全にパスできます。

フレームワーク属性による疎結合設計

コンストラクタプロモーションに Symfony の #[SerializedName] や Spatie Laravel Data の #[MapInputName] 属性を組み合わせることで、外部 API の snake_case JSON 仕様とドメイン内部の camelCase モデルを美しく分離できます。

よくあるトラブルと解決策

Cannot modify readonly property 実行時エラー

PHP 8.2 の readonly プロパティはコンストラクタ初期化後に値を変更できません。不変ウィザーメソッド(clone による複製更新)を採用するか、fromArray() 呼び出し時にすべての値を確定させてください。

ネストした連想配列がオブジェクト初期化時にアンパックできない

子オブジェクトの配列を直接引数に渡すのではなく、必ず対象子クラスの fromArray() ファクトリメソッドを経由してインスタンス化してください。

PHP 8.3+ で日付解析時に DateMalformedStringException が発生する

\DateTimeImmutable を初期化する前に日付文字列のフォーマットを検証するか、try-catch ブロックで捕捉して nullable な ?\DateTimeImmutable にフォールバックする安全設計を施してください。

よくある質問 (FAQ)

PHP 8.2 の readonly class を DTO に採用するメリットは何ですか?▼

初期化後のプロパティ書き換えを言語レベルで完全に遮断し、動的プロパティの追加も禁止されます。これにより完全な不変性が担保され、Swoole や RoadRunner などの非同期・並行環境でのスレッド安全性が確保され、防衛的コピーのオーバーヘッドもゼロになります。

コンストラクタプロパティプロモーションによりボイラープレートはどう削減されますか?▼

プロパティ定義、コンストラクタ引数、プロパティ代入文($this->prop = $prop)を個別に記述する代わりに、__construct() の引数宣言内に可視性、型、デフォルト値を集約でき、コード行数を 60% 以上削減できます。

Symfony Serializer や Laravel Spatie Data と互換性のある DTO を出力できますか?▼

はい。設定で属性(Attribute)出力を有効にすることで、Symfony の #[SerializedName] や Spatie Laravel Data の #[MapInputName] が付与され、snake_case JSON と camelCase PHP プロパティの相互変換がシームレスに行えます。

fromArray() は未定義キーや null のフィールドをどのように処理しますか?▼

入力データ全体を解析して欠落や null の可能性を検知し、nullable 型宣言(?string $name = null)と null 合体演算子($data['name'] ?? null)を自動適用するため、Undefined array key 警告を出さずに安全にハイドレーションできます。

DTO 生成時に入力 JSON データが外部サーバーに送信されることはありますか?▼

一切ありません。JSON のパース、AST 型推論、PHP コード生成はすべてお使いのブラウザ内部で JavaScript により完結して実行されるため、社内データや機密ペイロードが外部に流出するリスクは皆無です。

関連するおすすめ開発ツール

すべてのツール →
TypeScript to GraphQL SDL開発ツール

TypeScriptのインターフェース、型エイリアス、列挙型を本番環境向けGraphQLスキーマ定義言語(SDL)へ変換するための開発者リファレンス。

ツールを開く→
TypeScript インターフェースから Protocol Buffers proto3 への変換ツール開発ツール

TypeScriptのinterfaceやtype定義を、インクリメンタルなタグ番号を持つProtobuf 3構文のmessage、field、enumに変換します。

ツールを開く→
GitLab CI パイプライン生成リファレンス開発ツール

Node.js、Python、Go、Rust、Kaniko コンテナワークフローに対応した本番仕様の .gitlab-ci.yml パイプライン構築と最適化のための技術リファレンス。

ツールを開く→
Linux Supervisord (supervisord.conf) プログラム設定ジェネレーター開発ツール

自動再起動、プロセス並行数、ログ出力リダイレクト、環境変数、非特権ユーザー設定を含むSupervisordプログラム設定ブロックをブラウザ上で即座に生成します。

ツールを開く→
HAProxy ロードバランサー設定ジェネレーター開発ツール

HAProxyロードバランサー向けの本番環境対応設定ファイル生成および構文バリデーションツール。

ツールを開く→
Kubernetes Helm Chart (Chart.yaml & values.yaml) 生成ツール開発ツール

標準的なKubernetes Helm v3のChart.yaml、values.yaml、およびService、Ingress、リソース制限を備えたデプロイメントテンプレートを生成します。

ツールを開く→