Skip to content

/commands/php/json-encode-pretty-print

php json_encode pretty print (JSON_PRETTY_PRINT and other flags)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
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:

bash
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.php

Output

{"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 encoded

Without 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

FlagEffect
JSON_PRETTY_PRINTLine breaks and 4-space indentation
JSON_UNESCAPED_SLASHESWrite / instead of \/
JSON_UNESCAPED_UNICODEWrite UTF-8 characters as is instead of \uXXXX
JSON_THROW_ON_ERRORThrow JsonException instead of returning false (PHP 7.3+)
JSON_FORCE_OBJECTEncode every array, including lists and empty arrays, as an object
JSON_PRESERVE_ZERO_FRACTIONKeep 10.0 as 10.0 instead of 10
JSON_INVALID_UTF8_SUBSTITUTEReplace invalid UTF-8 bytes with U+FFFD instead of failing
JSON_NUMERIC_CHECKEncode numeric strings such as "42" as numbers (can surprise with phone numbers or IDs)

Send it as an HTTP response

php
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-1 in 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, without true it returns stdClass objects.
  • 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.

Sources