Utilo

JSON to PHP Converter – Free, Online, Private

Generate PHP 8 classes with constructor property promotion from a JSON sample, including list docblocks for arrays.

Input
Output

How to convert JSON to PHP

  1. Paste a JSON value. Objects become classes and arrays stay arrays with a docblock for the element type.
  2. Copy the file. It starts with declare(strict_types=1).
  3. Map the JSON into the constructor yourself, or hand the shape to a serializer. This page emits the type, not a fromJson method.

Constructor promotion

Each object is a class whose constructor promotes properties to public fields. The order follows the JSON text. Integers are int, other numbers are float, booleans are bool, strings are string, and nested objects use the class named after the property. PHP arrays are untyped at the language level, so an array property is array and a docblock says list<string> or list<Address> when the sample showed elements. An empty array is list<mixed>. A null value, or a key missing from some objects in an array, becomes a union with null and defaults to null, so the constructor can omit it. A JSON key that is not a legal or safe property name is camelCased, and the docblock records the original key.

Strict types and unions

declare(strict_types=1) applies to the file that contains it. Calls from another file are strict only if that file opts in too. Union types such as int|string|null need PHP 8.0, and a standalone null type needs 8.2. The sample's null field is emitted as null. If your runtime is older, change that property to mixed. There is no namespace and no jsonSerialize method. The class describes the shape. Hydrating it from json_decode($json, true) is a few assignments, or a library such as Symfony Serializer if you want that automated. This page does not call json_decode on a remote URL. It only reads what you paste.

Worked example

The user sample produces class Address with string $city and string $zip, then class Root with int $id, string $name, bool $active, array $tags, and Address $address. The docblock on Root says @param list<string> $tags. Nothing is nullable, because every key is present and no value is null. Add a second object to an array, drop a key from one of them, and convert again if you need to see an optional property. A key named class or list is suffixed so it does not collide with a PHP keyword. The classes are not final and not readonly. Add readonly on the class if you are on PHP 8.2 and want it.

What a sample cannot tell PHP

A string that happens to look like an email stays string. A number that is sometimes a numeric string stays whatever the sample used. Associative arrays and lists are both array in PHP; the docblock says list because JSON arrays are ordered. JSON objects become classes, not array shapes, so you do not get the string-key array style some codebases prefer. Duplicate inference with the TypeScript converter if you want to compare optionality. Both pages use the same rules: missing keys across merged objects are optional, empty arrays are unknown, and null is nullable. The work runs locally. Do not paste production data into a site that would have to upload it. This one does not.

Frequently asked questions

Does the class decode JSON by itself?

No. It is the typed shape. json_decode still returns arrays and stdClass until you assign the values.

Why is there a docblock on arrays?

PHP cannot write list<string> as a real property type. The docblock is what static analysis reads.

Which PHP version?

Constructor promotion and unions need PHP 8. A property typed only as null needs PHP 8.2.

Are properties readonly?

No. They are public promoted properties. Add readonly if you want immutability.