Back to blog
Tutorials8 min read

How to Parse JSON in PHP: json_decode and json_encode

Parse JSON in PHP with json_decode and json_encode: arrays vs objects, the associative flag, error handling with JSON_THROW_ON_ERROR, pretty printing, and the common encoding gotchas.

By Saifur Rahman Shochib

PHP makes JSON trivial with two built-in functions: json_decode to parse and json_encode to produce JSON. The functions are simple, but a few defaults — objects versus arrays, silent failures, and how associative arrays encode — trip up almost everyone at least once. This guide covers parsing JSON in PHP correctly, with modern error handling and the gotchas that cause real bugs.

json_decode: parse JSON into PHP

json_decode takes a JSON string and returns a PHP value. By default it returns objects: $data = json_decode($json); gives you a stdClass, so you access fields with arrow syntax like $data->name. This is fine, but many developers prefer arrays.

The associative flag: objects vs arrays

Pass true as the second argument to get associative arrays instead of objects: $data = json_decode($json, true); lets you use $data['name']. This is the most common pattern in PHP code because array access is familiar and easy to iterate with foreach. Choosing objects versus arrays is mostly a style decision — pick one and be consistent across your codebase.

Decode to an object or an associative arrayphp
$obj = json_decode($json);        // stdClass: $obj->name
$arr = json_decode($json, true);  // array:    $arr['name']

json_encode: produce JSON from PHP

json_encode converts a PHP value to a JSON string: echo json_encode($data);. It handles arrays, objects, and scalars. A key subtlety: an associative array encodes as a JSON object, while a sequential, zero-indexed array encodes as a JSON array. If your array keys are not a clean 0,1,2 sequence, PHP emits an object — a frequent source of surprise when an expected array comes out as an object.

Pretty printing and options

json_encode accepts bitmask flags. JSON_PRETTY_PRINT indents the output for readability, JSON_UNESCAPED_SLASHES keeps forward slashes unescaped, and JSON_UNESCAPED_UNICODE outputs multibyte characters directly instead of \u escapes — useful for non-Latin text. Combine them with the bitwise OR operator, for example json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE).

Error handling done right

Historically, json_decode returned null on failure, which is ambiguous because the JSON value null also decodes to null. The old way to disambiguate is json_last_error() and json_last_error_msg() after decoding. The modern, recommended approach is to pass the JSON_THROW_ON_ERROR flag so invalid JSON raises a JsonException you can catch with try/catch — explicit, clean, and impossible to ignore.

Modern error handling with exceptionsphp
try {
    $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    // handle invalid JSON explicitly
}

Common gotchas

  • A return of null may mean an error or a literal null — use JSON_THROW_ON_ERROR to tell them apart.
  • Associative arrays with non-sequential keys encode as JSON objects, not arrays.
  • Deeply nested data can hit the recursion depth limit; raise the depth argument if needed.
  • Invalid UTF-8 in strings causes json_encode to fail unless you handle encoding first.
  • Large integers may lose precision; use JSON_BIGINT_AS_STRING on decode when exact values matter.

Inspecting JSON outside PHP

When a payload behaves unexpectedly, it helps to look at the raw JSON. Paste it into a validator to confirm it is well-formed and find the exact error location, or a formatter to read the structure. That is quicker than scattering var_dump calls to discover the shape PHP actually decoded.

Frequently asked questions

What does the true in json_decode($json, true) do?

It tells json_decode to return associative arrays instead of stdClass objects. With true you access data as $data['key']; without it you access $data->key. The choice is stylistic — pick one consistently.

Why does json_decode return null?

Either the JSON was invalid or it literally contained null. To distinguish them, pass the JSON_THROW_ON_ERROR flag so invalid input throws a JsonException, or check json_last_error() after decoding.

Why is my PHP array encoded as a JSON object?

json_encode emits a JSON object whenever the array has non-sequential or string keys. Only a clean zero-indexed array (0,1,2,...) encodes as a JSON array. Re-index with array_values() if you need an array output.

How do I pretty-print JSON in PHP?

Pass the JSON_PRETTY_PRINT flag: json_encode($data, JSON_PRETTY_PRINT). Combine it with JSON_UNESCAPED_UNICODE and JSON_UNESCAPED_SLASHES for clean, readable output with literal characters.

How do I handle JSON errors in modern PHP?

Pass the JSON_THROW_ON_ERROR flag to json_decode or json_encode and wrap the call in try/catch for JsonException. This replaces the older json_last_error() checks with explicit, unmissable error handling.

Related tools

Try these tools

Keep reading

Related guides