/commands/php/json-encode-pretty-print
php json_encode pretty print (JSON_PRETTY_PRINT and other flags)
- tool
- PHP
- versions
- PHP 5.4+ (JSON_PRETTY_PRINT), JSON_THROW_ON_ERROR: PHP 7.3+
- os
- any
json_encode($data, JSON_PRETTY_PRINT) returns JSON with line breaks and four-space indentation instead of one long line. Combine it with JSON_UNESCAPED_SLASHES and JSON_UNESCAPED_UNICODE (using |) to keep / and non-ASCII characters readable, and with JSON_THROW_ON_ERROR to get an exception instead of a silent false.
Compare the flags
The example runs PHP 8.4 compiled to WebAssembly (php-wasm) through a small php wrapper around its CLI:
npm init -y >/dev/null
npm install --silent --no-audit --no-fund @php-wasm/node@3.1.56 @php-wasm/universal@3.1.56 >/dev/null 2>&1
cat > php.mjs <<'EOF'
import fs from "node:fs";
import { PHP } from "@php-wasm/universal";
import { loadNodeRuntime } from "@php-wasm/node";
const php = new PHP(await loadNodeRuntime("8.4", { emscriptenOptions: { processId: 1 } }));
php.mkdir("/app");
for (const f of fs.readdirSync(".").filter((f) => f.endsWith(".php"))) php.writeFile(`/app/${f}`, fs.readFileSync(f));
php.chdir("/app");
const r = await php.cli(["php", ...process.argv.slice(2)]);
process.stdout.write(await r.stdoutText);
process.stdout.write(await r.stderrText);
process.exit(await r.exitCode);
EOF
cat > pretty.php <<'EOF'
<?php
$data = ["name" => "Zoë", "url" => "https://errcodex.com/", "tags" => ["php", "json"], "meta" => []];
echo json_encode($data), "\n\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), "\n\n";
echo json_encode(["meta" => []], JSON_FORCE_OBJECT), "\n";
try {
json_encode(["bad" => "\xB1\x31"], JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
echo get_class($e), ": ", $e->getMessage(), "\n";
}
var_dump(json_encode(["bad" => "\xB1\x31"]));
echo json_last_error_msg(), "\n";
EOF
node php.mjs pretty.phpOutput
{"name":"Zo\u00eb","url":"https:\/\/errcodex.com\/","tags":["php","json"],"meta":[]}
{
"name": "Zoë",
"url": "https://errcodex.com/",
"tags": [
"php",
"json"
],
"meta": []
}
{"meta":{}}
JsonException: Malformed UTF-8 characters, possibly incorrectly encoded
bool(false)
Malformed UTF-8 characters, possibly incorrectly encodedWithout flags, / is escaped as \/ and ë becomes ë; with them, the output is readable as is. The invalid UTF-8 byte makes json_encode return false silently, or throw a JsonException with JSON_THROW_ON_ERROR.
Useful flags
| Flag | Effect |
|---|---|
| JSON_PRETTY_PRINT | Line breaks and 4-space indentation |
| JSON_UNESCAPED_SLASHES | Write / instead of \/ |
| JSON_UNESCAPED_UNICODE | Write UTF-8 characters as is instead of \uXXXX |
| JSON_THROW_ON_ERROR | Throw JsonException instead of returning false (PHP 7.3+) |
| JSON_FORCE_OBJECT | Encode every array, including lists and empty arrays, as an object |
| JSON_PRESERVE_ZERO_FRACTION | Keep 10.0 as 10.0 instead of 10 |
| JSON_INVALID_UTF8_SUBSTITUTE | Replace invalid UTF-8 bytes with U+FFFD instead of failing |
| JSON_NUMERIC_CHECK | Encode numeric strings such as "42" as numbers (can surprise with phone numbers or IDs) |
Send it as an HTTP response
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);Call header() before any output, otherwise PHP warns that headers are already sent.
Pitfalls
- Lists vs objects. Arrays with keys
0..n-1in order become JSON arrays; any other keys make an object.array_values()turns a filtered array back into a list. - Pretty printing in production APIs adds bytes; most clients do not need it. Use it for files, logs and debugging.
- Decoding is the reverse:
json_decode($json, true)returns arrays, withouttrueit returnsstdClassobjects. - Pretty-print JSON from the shell without PHP:
python -m json.tool file.json(see python -m json.tool).
Confirm it worked
The output spans several lines with four-space indentation, and json_decode($output, true) == $data is true.
FAQ
How do I change the indentation from 4 spaces to 2?
json_encode has no indent option; JSON_PRETTY_PRINT always uses four spaces. Post-process the string, for example with preg_replace on the leading spaces, or use a JSON library that supports a custom indent.
Why does json_encode return false?
Usually because a string is not valid UTF-8, or a value is INF or NAN. Call json_last_error_msg() to see why, or pass JSON_THROW_ON_ERROR to get a JsonException with the message.
Why is an empty PHP array encoded as [] and not {}?
An empty array has no keys, so it looks like a list. Pass JSON_FORCE_OBJECT, or use new stdClass() or (object) [] for values that must be JSON objects.