JSON7 min readExamples run on PHP 8.5.10

json_encode()

Learn how PHP 8.4 json_encode() turns arrays, objects and scalars into JSON strings, how flags change the output, and how to handle encoding failures.

Signature

json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false
Available since PHP 5.2.07.48.08.18.28.38.48.5All versions →

Purpose

json_encode() converts a PHP value into a string of JSON text. It is the usual way to build API responses, store structured data in a text column, or pass data to JavaScript. Arrays and objects are converted recursively, so a nested structure becomes nested JSON in a single call.

Signature

Parameters and defaults

  • $value is the value to encode. It can be any type except a resource. Every string must be valid UTF-8.
  • $flags is a bitmask combined with |. The default 0 gives compact output with escaped slashes and escaped non-ASCII characters. Commonly used flags:
    • JSON_PRETTY_PRINT adds newlines and indentation.
    • JSON_UNESCAPED_SLASHES leaves / as it is.
    • JSON_UNESCAPED_UNICODE writes multibyte characters directly instead of as \uXXXX escapes.
    • JSON_PRESERVE_ZERO_FRACTION keeps 12.0 as 12.0 instead of 12.
    • JSON_FORCE_OBJECT turns every array into a JSON object.
    • JSON_NUMERIC_CHECK converts numeric strings into numbers.
    • JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS and JSON_HEX_QUOT escape characters that matter when JSON is embedded in HTML.
    • JSON_INVALID_UTF8_IGNORE and JSON_INVALID_UTF8_SUBSTITUTE deal with bad UTF-8 instead of failing.
    • JSON_PARTIAL_OUTPUT_ON_ERROR substitutes values it cannot encode.
    • JSON_THROW_ON_ERROR throws a JsonException instead of returning false.
  • $depth is the maximum nesting depth and must be greater than zero. The default is 512.

Float output also depends on the serialize_precision setting.

Return value and failures

On success you get a JSON string. On failure the function returns false, unless JSON_THROW_ON_ERROR is set, in which case it throws JsonException. Typical causes of failure are invalid UTF-8, exceeding $depth, NAN or INF floats, and unsupported types such as resources. Without the throw flag, call json_last_error() or json_last_error_msg() to find out why.

Example 1: arrays, lists and objects

PHP arrays map to either JSON arrays or JSON objects. A list with keys 0, 1, 2... in order becomes a JSON array. Any other key pattern becomes an object, with the keys written as strings.

Example
<?php
$user = ['id' => 7, 'name' => 'Ana', 'tags' => ['php', 'json'], 'active' => true, 'score' => null];
echo json_encode($user), "\n";
echo json_encode([1, 2, 3]), "\n";
echo json_encode([1 => 'a', 2 => 'b']), "\n";
echo json_encode([]), "\n";
echo json_encode([], JSON_FORCE_OBJECT), "\n";
Output
{"id":7,"name":"Ana","tags":["php","json"],"active":true,"score":null}
[1,2,3]
{"1":"a","2":"b"}
[]
{}

Example 2: flags that change formatting

By default, slashes and non-ASCII characters are escaped, and a float with a zero fraction loses its .0. Flags let you change each of those.

Example
<?php
$data = ['url' => 'https://example.com/a', 'city' => "Z\u{fc}rich", 'price' => 12.0];
echo json_encode($data), "\n";
echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION), "\n";
Output
{"url":"https:\/\/example.com\/a","city":"Z\u00fcrich","price":12}
{"url":"https://example.com/a","city":"Zürich","price":12.0}

Example 3: handling errors

A string that is not valid UTF-8 cannot be encoded. You can check for false, throw an exception, or ask PHP to substitute the replacement character.

Example
<?php
$bad = ["name" => "\xB1\x31"];
var_dump(json_encode($bad));
echo json_last_error_msg(), "\n";
try {
    json_encode($bad, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo get_class($e), ': ', $e->getMessage(), ' (', $e->getCode(), ")\n";
}
echo json_encode($bad, JSON_INVALID_UTF8_SUBSTITUTE), "\n";
Output
bool(false)
Malformed UTF-8 characters, possibly incorrectly encoded
JsonException: Malformed UTF-8 characters, possibly incorrectly encoded (5)
{"name":"\ufffd1"}

Edge cases

  • Gaps in keys. If you unset() an element from a list, the keys are no longer a continuous sequence from 0, so the result becomes a JSON object. Use array_values() first when you need an array.
  • Empty arrays. An empty PHP array is always []. To get {} use JSON_FORCE_OBJECT or encode an stdClass object.
  • Objects. Only public properties are included by default. A class that implements JsonSerializable controls its own output through jsonSerialize().
  • Scalar top-level values. Encoding a string, int, float or bool produces a bare JSON value such as "hi" or true. Most decoders accept this, but some do not, so test your consumer.
  • Numeric strings. JSON_NUMERIC_CHECK turns "1.2e3" into 1200. That can damage identifiers, phone numbers or ZIP codes with leading zeros, so use it with care.
  • Pretty printing. JSON_PRETTY_PRINT is for readability. It changes whitespace only, not the data.

Common mistakes

  1. Echoing the result without checking for false. A failed call can silently produce an empty response.
  2. Passing text in a legacy encoding such as ISO-8859-1. Convert it to UTF-8 first.
  3. Assuming an array always becomes a JSON array. Non-sequential keys change the shape.
  4. Using JSON_NUMERIC_CHECK globally and altering string data you wanted to keep as strings.
  5. Forgetting that JSON_HEX_* flags exist when printing JSON inside an HTML <script> block.
  6. Relying on the default serialize_precision being identical on every server. Keep the ini setting consistent between environments.
  • json_decode() parses JSON text back into PHP values.
  • json_last_error() returns the last error code.
  • json_last_error_msg() returns the last error as text.
  • JsonSerializable customizes how objects are encoded.
  • serialize() produces a PHP-specific storable representation instead of JSON.

Recap

json_encode() turns PHP values into JSON text. Sequential lists become arrays and everything else becomes objects. Flags control escaping, number formatting and layout. Failures return false unless you request exceptions with JSON_THROW_ON_ERROR, which is usually the safer choice in new code.

Tested examples

Arrays, lists and objects
<?php
$user = ['id' => 7, 'name' => 'Ana', 'tags' => ['php', 'json'], 'active' => true, 'score' => null];
echo json_encode($user), "\n";
echo json_encode([1, 2, 3]), "\n";
echo json_encode([1 => 'a', 2 => 'b']), "\n";
echo json_encode([]), "\n";
echo json_encode([], JSON_FORCE_OBJECT), "\n";
Output
{"id":7,"name":"Ana","tags":["php","json"],"active":true,"score":null}
[1,2,3]
{"1":"a","2":"b"}
[]
{}
Flags that change formatting
<?php
$data = ['url' => 'https://example.com/a', 'city' => "Z\u{fc}rich", 'price' => 12.0];
echo json_encode($data), "\n";
echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION), "\n";
Output
{"url":"https:\/\/example.com\/a","city":"Z\u00fcrich","price":12}
{"url":"https://example.com/a","city":"Zürich","price":12.0}
Handling encoding errors
<?php
$bad = ["name" => "\xB1\x31"];
var_dump(json_encode($bad));
echo json_last_error_msg(), "\n";
try {
    json_encode($bad, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo get_class($e), ': ', $e->getMessage(), ' (', $e->getCode(), ")\n";
}
echo json_encode($bad, JSON_INVALID_UTF8_SUBSTITUTE), "\n";
Output
bool(false)
Malformed UTF-8 characters, possibly incorrectly encoded
JsonException: Malformed UTF-8 characters, possibly incorrectly encoded (5)
{"name":"\ufffd1"}