Signature
json_decode(string $json, ?bool $associative = null, int $depth = 512, int $flags = 0): mixedPurpose
json_decode() takes a JSON-encoded string and converts it into a PHP value. You use it whenever data arrives as JSON text, for example a request body, a stored settings string or an API response already held in memory. The result can be an array, an object, a string, an int, a float, a bool or null, depending on what the JSON contains.
Signature
Parameters and defaults
$json: the JSON text. It must be UTF-8. PHP accepts a slightly wider syntax than the strict RFC, but you should send strict JSON.$associative: withtrue, JSON objects become associative arrays. Withfalse, they becomestdClassobjects. With the defaultnull, the choice depends on whetherJSON_OBJECT_AS_ARRAYis set in$flags. Without that flag you get objects.$depth: the maximum nesting depth, 512 by default. It must be greater than 0 and no larger than 2147483647.$flags: a bitmask. The documented flags areJSON_BIGINT_AS_STRING,JSON_INVALID_UTF8_IGNORE,JSON_INVALID_UTF8_SUBSTITUTE,JSON_OBJECT_AS_ARRAYandJSON_THROW_ON_ERROR.
Return value and failure cases
The return type is mixed. The literals true, false and null decode to their PHP counterparts. On failure the function returns null when the text cannot be decoded or is nested deeper than $depth.
This creates an ambiguity, because the valid JSON text null also decodes to null. To tell the two cases apart, either call json_last_error() or json_last_error_msg() right after the call, or pass JSON_THROW_ON_ERROR. That flag makes failures throw a JsonException instead of returning null.
An out-of-range $depth throws a ValueError.
Example 1: decoding to an associative array
Pass true as the second argument when you want to work with plain arrays.
$json = '{"name":"Ada","langs":["PHP","SQL"],"active":true,"score":9.5}';
$data = json_decode($json, true);
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo $data['langs'][1], PHP_EOL;
var_dump($data['active']);{"name":"Ada","langs":["PHP","SQL"],"active":true,"score":9.5}
SQL
bool(true)
JSON arrays become PHP lists, JSON objects become associative arrays, and true stays a real boolean.
Example 2: decoding to objects
Without the second argument, JSON objects become stdClass instances. Keys that are not valid PHP identifiers, such as ones containing a hyphen, are read with braces and quotes.
$json = '{"foo-bar":12345,"nested":{"x":1}}';
$obj = json_decode($json);
echo $obj->{'foo-bar'}, PHP_EOL;
echo get_class($obj->nested), PHP_EOL;
echo $obj->nested->x, PHP_EOL;12345 stdClass 1
Example 3: failing loudly with JSON_THROW_ON_ERROR
The throw flag removes the ambiguity between invalid JSON and the literal null.
function decodeOrMessage(string $json): string
{
try {
$value = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
return json_encode($value);
} catch (JsonException $e) {
return 'error: ' . $e->getMessage();
}
}
echo decodeOrMessage('{"ok":true}'), PHP_EOL;
echo decodeOrMessage("{'ok':true}"), PHP_EOL;
echo decodeOrMessage('null'), PHP_EOL;{"ok":true}
error: Syntax error
null
The single-quoted text is not valid JSON, so it throws. The text null is valid and decodes without error.
Edge cases
- Depth: every level of nesting counts toward
$depth. In the manual's example, a structure with three nested arrays holding strings decodes with a depth of 4 but fails with a depth of 3, reporting "Maximum stack depth exceeded". - Large integers: an integer too large for a PHP int is decoded as a float and loses precision. Pass
JSON_BIGINT_AS_STRINGto receive it as a string instead. - Scalars at the top level: a JSON document may be just a number, a string or
null. The result is then not an array or object. - Empty input: an empty string is not valid JSON, so without the throw flag you get
nulland an error code. - Encoding: the input must be UTF-8. The flags
JSON_INVALID_UTF8_IGNOREandJSON_INVALID_UTF8_SUBSTITUTEcontrol what happens to invalid byte sequences.
Common mistakes
- Writing JavaScript, not JSON. Single quotes, unquoted keys and trailing commas are all rejected. Names and string values need double quotes.
- Treating
nullas proof of failure. It may be a valid result. Check the error state or useJSON_THROW_ON_ERROR. - Forgetting the second argument. Code written for arrays, like
$data['name'], breaks on astdClassobject. - Trusting the shape of the data. Decoded input can contain any type in any position, so check that keys exist and have the expected types before using them.
- Assuming large IDs survive. Numeric identifiers beyond the int range silently become floats unless you opt into strings.
Related functions
json_encode()converts a PHP value into JSON text.json_last_error()returns the error code of the last JSON operation.json_last_error_msg()returns a readable message for that error.json_validate()checks whether a string is valid JSON, which is useful when you do not need the decoded value.
Recap
Use json_decode() to turn UTF-8 JSON text into PHP values. Choose arrays with true or objects by default, and raise $depth only if you genuinely need deeper nesting. Prefer JSON_THROW_ON_ERROR so that a bad document is never confused with a valid null. Remember that big integers become floats unless you request strings.
Tested examples
$json = '{"name":"Ada","langs":["PHP","SQL"],"active":true,"score":9.5}';
$data = json_decode($json, true);
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo $data['langs'][1], PHP_EOL;
var_dump($data['active']);{"name":"Ada","langs":["PHP","SQL"],"active":true,"score":9.5}
SQL
bool(true)
$json = '{"foo-bar":12345,"nested":{"x":1}}';
$obj = json_decode($json);
echo $obj->{'foo-bar'}, PHP_EOL;
echo get_class($obj->nested), PHP_EOL;
echo $obj->nested->x, PHP_EOL;12345 stdClass 1
function decodeOrMessage(string $json): string
{
try {
$value = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
return json_encode($value);
} catch (JsonException $e) {
return 'error: ' . $e->getMessage();
}
}
echo decodeOrMessage('{"ok":true}'), PHP_EOL;
echo decodeOrMessage("{'ok':true}"), PHP_EOL;
echo decodeOrMessage('null'), PHP_EOL;{"ok":true}
error: Syntax error
null