JSON Handling
Learn how to convert PHP data to JSON and back using json_encode() and json_decode(), and build a small JSON API response.
Introduction
JSON (JavaScript Object Notation) is the format nearly every modern web API speaks. Whether you are building an endpoint for a JavaScript frontend, a mobile app, or another server, you will almost certainly need to convert PHP data into JSON — and parse JSON back into PHP data.
PHP makes this easy with two built-in functions: json_encode() and json_decode(). This lesson covers both, along with the common pitfalls that trip up beginners.
- What JSON is and why it is used so widely.
- How to convert PHP arrays and objects into JSON with json_encode().
- How to parse JSON strings back into PHP data with json_decode().
- The difference between decoding to an associative array and decoding to an object.
- How to check for JSON errors and build a small JSON API response.
What Is JSON?
JSON is a lightweight, text-based data format for representing structured data — objects, arrays, strings, numbers, booleans, and null. It grew out of JavaScript syntax but is now language-independent and used everywhere: REST APIs, configuration files, and message queues.
{
"name": "Jane Doe",
"age": 27,
"active": true,
"roles": ["editor", "author"]
}JSON is compact, human-readable, and maps naturally onto arrays and objects in almost every programming language, which is why it replaced XML as the default format for most web APIs.
json_encode(): PHP to JSON
json_encode() converts a PHP value — usually an array or object — into a JSON-formatted string.
<?php
$user = [
"name" => "Jane Doe",
"age" => 27,
"active" => true,
"roles" => ["editor", "author"],
];
echo json_encode($user);{"name":"Jane Doe","age":27,"active":true,"roles":["editor","author"]}That single line of output is valid but hard to read. Passing the JSON_PRETTY_PRINT flag formats the result with indentation and line breaks, which is useful for debugging or for developer-facing endpoints.
<?php
echo json_encode($user, JSON_PRETTY_PRINT);{
"name": "Jane Doe",
"age": 27,
"active": true,
"roles": [
"editor",
"author"
]
}json_decode(): JSON to PHP
json_decode() takes a JSON string and converts it back into PHP data. By default, it returns objects (instances of stdClass) rather than arrays.
<?php
$json = '{"name":"Jane Doe","age":27,"roles":["editor","author"]}';
$data = json_decode($json);
echo $data->name . "\n";
echo $data->age . "\n";
echo $data->roles[0];Jane Doe
27
editorAssociative Arrays vs Objects
Passing true as the second argument to json_decode() tells it to return associative arrays instead of stdClass objects. Most PHP developers prefer this, since arrays are usually easier to work with using familiar syntax like $data["name"].
<?php
$json = '{"name":"Jane Doe","age":27,"roles":["editor","author"]}';
$data = json_decode($json, true);
echo $data["name"] . "\n";
echo $data["age"] . "\n";
echo $data["roles"][0];Jane Doe
27
editorjson_decode($json) — Object
- Access with -> like $data->name
- Returns instances of stdClass
- Nested JSON objects also become stdClass
- Slightly closer to typical JavaScript style
json_decode($json, true) — Array
- Access with [] like $data["name"]
- Returns plain associative arrays
- Nested JSON objects also become arrays
- Usually more convenient for typical PHP code
Handling Errors
If the JSON string is malformed, json_decode() quietly returns null instead of throwing an error. Since a valid JSON document can also decode to null (the JSON value "null" itself), checking for null is not reliable on its own — always check json_last_error() as well.
<?php
$badJson = '{"name": "Jane", "age": }'; // malformed: missing value
$data = json_decode($badJson, true);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "Failed to parse JSON: " . json_last_error_msg();
} else {
echo "Parsed successfully.";
}Failed to parse JSON: Syntax errorExample: A Tiny JSON API Response
Here is a minimal example of a PHP script that could act as a JSON API endpoint: it builds some data, encodes it, and sends it with the correct content type.
<?php
header("Content-Type: application/json");
$products = [
["id" => 1, "name" => "Keyboard", "price" => 49.99],
["id" => 2, "name" => "Mouse", "price" => 19.99],
];
$response = [
"status" => "success",
"count" => count($products),
"data" => $products,
];
echo json_encode($response, JSON_PRETTY_PRINT);{
"status": "success",
"count": 2,
"data": [
{
"id": 1,
"name": "Keyboard",
"price": 49.99
},
{
"id": 2,
"name": "Mouse",
"price": 19.99
}
]
}Setting the Content-Type header to application/json tells the client — a browser, a mobile app, or another server — exactly how to interpret the response body.
Common Mistakes
- Assuming json_decode() throws an exception on invalid input — it returns null and you must check json_last_error() yourself.
- Forgetting the true second argument and then trying to use array syntax on a stdClass object.
- Not setting the Content-Type: application/json header on API responses.
- Trying to json_encode() a resource or an object with circular references, which will fail silently or produce unexpected results.
Best Practices
- Decide once per project whether you prefer objects or associative arrays from json_decode(), and be consistent.
- Always check json_last_error() after decoding data from an external or untrusted source.
- Use JSON_PRETTY_PRINT for debug output or developer-facing endpoints, but consider omitting it for production traffic to save bandwidth.
- Set the Content-Type: application/json header whenever your script's output is meant to be consumed as JSON.
- Use JSON_THROW_ON_ERROR (PHP 7.3+) as a third flag argument if you prefer exceptions over manually checking json_last_error().
Frequently Asked Questions
Does json_decode() throw an exception if the JSON is invalid?
Not by default — it returns null. You can pass the JSON_THROW_ON_ERROR flag to make it throw a JsonException instead.
What is the difference between json_decode($json) and json_decode($json, true)?
Without true, JSON objects become stdClass instances accessed with ->; with true, they become associative arrays accessed with [].
Why would I use JSON_PRETTY_PRINT?
It formats the JSON output with indentation and line breaks, which makes it much easier to read while debugging or developing.
Can json_encode() handle nested arrays and objects?
Yes, json_encode() recursively encodes any nested arrays or objects it finds inside the value you pass to it.
Key Takeaways
- json_encode() converts PHP arrays or objects into a JSON string.
- JSON_PRETTY_PRINT formats that JSON string for human readability.
- json_decode() parses a JSON string back into PHP data, as objects by default.
- Passing true as the second argument to json_decode() returns associative arrays instead.
- Always check json_last_error() when decoding data you did not generate yourself.
Summary
JSON is the backbone of modern web communication, and PHP's json_encode() and json_decode() make working with it straightforward. The key details to remember are choosing between objects and associative arrays, and always checking for decoding errors on untrusted input.
Next, you will look at XML, an older but still relevant data format, and see how PHP can read and navigate it.
- You can convert PHP data into JSON with json_encode().
- You can parse JSON back into PHP data with json_decode().
- You understand associative arrays vs objects when decoding.
- You can check for and handle JSON errors safely.