What does json_decode() do?
json_decode() parses a JSON string. By default JSON objects become stdClass objects (access with ->); pass true as the second argument to get associative arrays instead (access with ['key']).
Syntax
json_decode(string $json, ?bool $associative = null, int $depth = 512, int $flags = 0): mixed
Parameters
$json- The JSON string to decode. It must be UTF-8.$associative-true: objects become associative arrays.false/null: objects becomestdClass(unlessJSON_OBJECT_AS_ARRAYis set in flags).$depth- Maximum nesting depth.$flags- Bitmask such asJSON_THROW_ON_ERROR,JSON_BIGINT_AS_STRING,JSON_OBJECT_AS_ARRAY.
Return value
The decoded value (array, object, string, int, float, bool or null). Invalid JSON returns null, so check json_last_error() or use JSON_THROW_ON_ERROR.
json_decode() examples
Every example below shows the exact output it produces. Paste any of them into the editor above (or the online compiler) to run it.
1. Object vs associative array
<?php
$json = '{"name":"John","age":30,"city":"New York"}';
$obj = json_decode($json);
echo $obj->name . "\n";
$arr = json_decode($json, true);
echo $arr["city"] . "\n";
var_dump($arr);
Output:
John
New York
array(3) {
["name"]=>
string(4) "John"
["age"]=>
int(30)
["city"]=>
string(8) "New York"
}
2. Read nested JSON
<?php
$json = '{"user":{"name":"Ann","roles":["admin","editor"]},"orders":[{"id":1,"total":9.5},{"id":2,"total":20}]}';
$data = json_decode($json, true);
echo $data["user"]["name"] . "\n";
echo $data["user"]["roles"][1] . "\n";
foreach ($data["orders"] as $order) {
echo "Order {$order['id']}: {$order['total']}\n";
}
Output:
Ann editor Order 1: 9.5 Order 2: 20
3. Handle invalid JSON
<?php
$invalid = '{"name": "John",}';
var_dump(json_decode($invalid, true));
echo json_last_error_msg() . "\n";
try {
json_decode($invalid, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
Output:
NULL Syntax error Error: Syntax error
4. Large integers
<?php
$json = '{"id": 12345678901234567890}';
var_dump(json_decode($json, true)["id"]);
var_dump(json_decode($json, true, 512, JSON_BIGINT_AS_STRING)["id"]);
Output:
float(1.2345678901234567E+19) string(20) "12345678901234567890"
Decoding a JSON request body (save.php example)
APIs and JavaScript fetch() calls usually send JSON in the request body, not as form fields, so $_POST stays empty. Read the raw body from php://input, decode it with exceptions enabled, validate it, and store it with a prepared statement. This snippet needs a web server and database, so it is shown without output.
<?php
// save.php
header('Content-Type: application/json');
try {
$data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
$name = trim($data['name'] ?? '');
$email = filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL);
if ($name === '' || $email === false) {
http_response_code(422);
echo json_encode(['error' => 'Name and a valid email are required']);
exit;
}
$pdo = new PDO('mysql:host=localhost;dbname=app;charset=utf8mb4', 'user', 'password', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$stmt = $pdo->prepare('INSERT INTO contacts (name, email) VALUES (:name, :email)');
$stmt->execute(['name' => $name, 'email' => $email]);
echo json_encode(['id' => (int) $pdo->lastInsertId()]);
Common mistakes and gotchas
- null is ambiguous:
json_decode("null")and invalid JSON both returnnull. UseJSON_THROW_ON_ERROR(PHP 7.3+) to tell them apart. - Object vs array access: "Cannot use object of type stdClass as array" means you forgot the
trueargument (or should use->). - Trailing commas and single quotes are not valid JSON and cause a "Syntax error".
- Validation only: on PHP 8.3+,
json_validate($json)checks syntax without building the array.