Menu

PHP json_decode(): Parse JSON into Arrays or Objects

json_decode($json, true) turns a JSON string into a PHP associative array; without true you get stdClass objects. Learn nested values, error handling with JSON_THROW_ON_ERROR, json_validate() and why json_decode returns null.

This page includes runnable editors - edit, run, and see output instantly.

json_decode($json, true) turns a JSON string into PHP values, with every JSON object as an associative array. Leave out true and JSON objects become stdClass objects instead, read with ->. Invalid JSON gives null.

Output:

Ada
js
Ada
php
Array
(
    [name] => Ada
    [age] => 36
    [langs] => Array
        (
            [0] => php
            [1] => js
        )

    [admin] => 1
)

JSON arrays always become PHP lists, whichever mode you choose. Going the other way, from PHP to JSON, is json_encode().

Associative array or object: true vs false

Both modes hold the same data; pick the one that reads better in your code. Arrays work with every array function (array_column, array_map, isset($data['key'])), so most code passes true. Objects need the brace syntax for keys that are not valid property names, such as keys with a hyphen or a number:

Output:

Ada zero London
Ada zero London
object(stdClass)#2 (1) {
  ["city"]=>
  string(6) "London"
}

The fourth parameter takes flags. JSON_OBJECT_AS_ARRAY gives arrays too, but only while the second argument is null (its default): json_decode($json, flags: JSON_OBJECT_AS_ARRAY) returns arrays, while json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY) still returns objects.

Loop over nested JSON

API responses are usually a list of objects inside an object. Decode once, then walk it with foreach, and use ?? for fields that may be missing:

Output:

#1 Ada <ada@example.com> roles: admin, editor
#2 Linus <no email> roles: none
#3 Grace <grace@example.com> roles: editor
Array
(
    [1] => Ada
    [2] => Linus
    [3] => Grace
)

Handle invalid JSON

json_decode() returns null for invalid JSON, but null is also the correct result for the JSON text null, so null alone does not tell you whether it failed. json_last_error_msg() gives the reason of the last call. The cleaner way is JSON_THROW_ON_ERROR, which throws a JsonException:

Output:

NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error

The third argument, 512, is the maximum nesting depth (the default). With named arguments you can skip it: json_decode($json, true, flags: JSON_THROW_ON_ERROR).

Check if a string is valid JSON with json_validate()

PHP 8.3 added json_validate(). It answers true or false without building the decoded arrays, so it uses less memory than decoding when all you need is a yes or no, for example to reject a request body early:

Output:

'{"a": 1}'    valid
'[1, 2, 3]'   valid
'"text"'      valid
'{a: 1}'      invalid: Syntax error
'{\'a\': 1}'  invalid: Syntax error
''            invalid: Syntax error

If you will use the data anyway, skip json_validate() and decode with JSON_THROW_ON_ERROR: validating first parses the string twice.

Read a JSON file

Read the file with file_get_contents() and decode the string. This block writes settings.json first so there is a file to read:

Output:

Theme: dark
Plugins: 2
{
    "theme": "dark",
    "fontSize": 16,
    "plugins": [
        "git",
        "lint"
    ]
}

Why json_decode returns null: the usual causes

JSON is stricter than JavaScript and PHP array syntax. Every string below looks reasonable and every one returns null. Run it to see the reason for each, then fix one and run it again:

Output:

single quotes    Syntax error
unquoted key     Syntax error
trailing comma   Syntax error
comment          Syntax error
byte order mark  Syntax error
too deep         Maximum stack depth exceeded
float(1.2345678901234567E+19)
string(20) "12345678901234567890"

A byte order mark is invisible in most editors and is the classic reason a JSON file "looks fine" but will not decode. Strip it with $text = preg_replace('/^\xEF\xBB\xBF/', '', $text); before decoding.

Frequently Asked Questions

How do I convert JSON to an array in PHP?

Pass true as the second argument: json_decode('{"name":"Ada"}', true) returns ['name' => 'Ada'], so you read values with $data['name']. Without true, JSON objects become stdClass objects and you write $data->name.

Why does json_decode return null?

The JSON is invalid (single quotes, a trailing comma, unquoted keys, a byte order mark), it is nested deeper than the depth limit, or the JSON really is null. Check json_last_error_msg(), or decode with JSON_THROW_ON_ERROR to get a JsonException with the reason.

How do I check if a string is valid JSON in PHP?

Since PHP 8.3, json_validate($string) returns true or false without building the decoded value. On older versions, decode it and check json_last_error() === JSON_ERROR_NONE.

How do I read a JSON file in PHP?

Read the file, then decode it: $data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);. file_get_contents() returns false if the file is missing, so check that first.

How do I access a JSON key with a hyphen in PHP?

Decode to an array and use $data['first-name'], or with objects use braces: $obj->{'first-name'}. The same brace syntax works for keys that are numbers, such as $obj->{'0'}.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED