DevToolsmith

JSON to PHP Class Converter

Paste JSON to generate typed PHP 8 classes: readonly promoted properties, nullable types, list docblocks for arrays and a fromArray() factory that builds nested objects from json_decode.

Runs 100% in your browser — nothing is uploaded

JSON
Tip: drop a file here361 chars · 361 bytes · 14 lines
PHP classes
2,078 chars · 2,078 bytes · 80 lines

Tip: paste an array of several objects — keys missing from some of them become optional (?type).

Example

JSON input
{
  "order_id": "A-1001",
  "total": 59.9,
  "paid": true,
  "customer": {
    "id": 7,
    "email": "ada@example.com",
    "phone": null
  },
  "items": [
    {
      "sku": "MUG-01",
      "qty": 2
    },
    {
      "sku": "TEE-04",
      "qty": 1
    }
  ]
}
Generated PHP (root name: Order)
<?php

declare(strict_types=1);

// $order = Order::fromArray(json_decode($json, true, flags: JSON_THROW_ON_ERROR));

final class Order
{
    public function __construct(
        public readonly string $orderId,
        public readonly float $total,
        public readonly bool $paid,
        public readonly Customer $customer,
        /** @var list<Item> */
        public readonly array $items,
    ) {
    }

    /** @param array<string, mixed> $data */
    public static function fromArray(array $data): self
    {
        return new self(
            orderId: $data['order_id'],
            total: $data['total'],
            paid: $data['paid'],
            customer: Customer::fromArray($data['customer']),
            items: array_map(fn ($item) => Item::fromArray($item), $data['items']),
        );
    }
}

final class Customer
{
    public function __construct(
        public readonly int $id,
        public readonly string $email,
        public readonly mixed $phone,
    ) {
    }

    /** @param array<string, mixed> $data */
    public static function fromArray(array $data): self
    {
        return new self(
            id: $data['id'],
            email: $data['email'],
            phone: $data['phone'] ?? null,
        );
    }
}

final class Item
{
    public function __construct(
        public readonly string $sku,
        public readonly int $qty,
    ) {
    }

    /** @param array<string, mixed> $data */
    public static function fromArray(array $data): self
    {
        return new self(
            sku: $data['sku'],
            qty: $data['qty'],
        );
    }
}
  • order_id became $orderId; fromArray() still reads $data['order_id'].
  • phone is null, so its type is unknown and it becomes mixed. Paste a sample with a value to get ?string.
  • items is an array of objects, so it gets an Item class and an array_map.

Using the classes

$order = Order::fromArray(json_decode($json, true, flags: JSON_THROW_ON_ERROR));

echo $order->customer->email;
foreach ($order->items as $item) {
    echo "{$item->sku} × {$item->qty}\n";
}
Laravel
// Laravel: build the DTO from a validated request or an HTTP response
$order = Order::fromArray($request->validated());
$order = Order::fromArray(Http::get($url)->throw()->json());

Writing the frontend for the same API? Generate TypeScript interfaces too. For a machine-checkable contract, create a JSON Schema.

Frequently asked questions

How do I convert JSON to a PHP class?

Paste a JSON sample into the tool above. It writes a final class for every object, with typed constructor-promoted properties, nullable types for values that can be null or missing, list<…> docblocks for arrays, and a static fromArray() that builds the object, including nested objects, from json_decode($json, true).

Which PHP version do I need?

Constructor property promotion and named arguments need PHP 8.0, readonly properties need PHP 8.1. Untick readonly for PHP 8.0. Everything else works on any supported PHP version.

Why fromArray() instead of json_decode into the class?

json_decode only produces arrays or stdClass objects; it can’t create your classes. fromArray() maps each key to the matching property and builds nested objects, so you get typed objects that your IDE and static analysers such as PHPStan and Psalm understand.

Why is a float property given an integer?

json_decode returns an int for numbers written without a decimal point, such as 60. PHP converts int to float for float properties even with strict_types=1, so this works without any cast.

What about very large integers?

Integers beyond 64 bits would be rounded to float by json_decode. The converter types them as string and adds the JSON_BIGINT_AS_STRING flag to the decode example so they stay exact.