json_encode() turns a PHP value into a JSON string.
<?php
$user = [
"id" => 7,
"name" => "Ana",
"tags" => ["php", "web"],
"active" => true,
"score" => 9.5,
"manager" => null,
];
echo json_encode($user);
{"id":7,"name":"Ana","tags":["php","web"],"active":true,"score":9.5,"manager":null}
List or object?
- An array with keys
0, 1, 2 ...in order becomes a JSON array[...]. - An array with other keys becomes a JSON object
{...}.
<?php
echo json_encode(["a", "b"]) . "\n";
echo json_encode([1 => "a", 2 => "b"]) . "\n"; // keys do not start at 0: an object
echo json_encode([]) . "\n"; // empty array
echo json_encode(new stdClass()); // empty object
["a","b"]
{"1":"a","2":"b"}
[]
{}
If you filter an array and the keys have gaps, wrap it with array_values() to get a JSON array.
Flags
A second argument sets options. Combine flags with |.
<?php
$data = ["name" => "Zoë", "url" => "https://example.com/a/b"];
echo json_encode($data) . "\n";
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
echo json_encode(["a" => 1, "b" => [2, 3]], JSON_PRETTY_PRINT);
{"name":"Zo\u00eb","url":"https:\/\/example.com\/a\/b"}
{"name":"Zoë","url":"https://example.com/a/b"}
{
"a": 1,
"b": [
2,
3
]
}
| Flag | Effect |
|---|---|
JSON_PRETTY_PRINT | Indents the output for people |
JSON_UNESCAPED_UNICODE | Keeps characters like ë and Hindi letters, instead of \u00eb |
JSON_UNESCAPED_SLASHES | Keeps / as it is |
JSON_THROW_ON_ERROR | Throw a JsonException on failure |
JSON_NUMERIC_CHECK | Turns numeric strings into numbers (avoid, it changes data) |
JSON_HEX_TAG, JSON_HEX_AMP, … | Safe embedding in HTML (see XSS) |
JSON_PRESERVE_ZERO_FRACTION | Keeps 10.0 as 10.0 instead of 10 |
Errors: always handle failure
json_encode() can fail, for example when text is not valid UTF-8. By default it returns false quietly.
<?php
$bad = ["name" => "caf" . chr(233)]; // a Latin-1 byte, not valid UTF-8
var_dump(json_encode($bad));
echo json_last_error_msg() . "\n";
try {
json_encode($bad, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
echo "Exception: " . $e->getMessage();
}
bool(false)
Malformed UTF-8 characters, possibly incorrectly encoded
Exception: Malformed UTF-8 characters, possibly incorrectly encoded
Use JSON_THROW_ON_ERROR in new code, so failures cannot be ignored.
Objects
json_encode() includes an object’s public properties.
<?php
class Product
{
public function __construct(
public string $name,
public float $price,
private string $secretNote = "internal",
) {}
}
echo json_encode(new Product("Pen", 12.5));
{"name":"Pen","price":12.5}
The private property is left out.
Control the output: JsonSerializable
Implement JsonSerializable to decide exactly what is output.
<?php
class User implements JsonSerializable
{
public function __construct(
private int $id,
private string $name,
private string $passwordHash,
) {}
public function jsonSerialize(): array
{
return ["id" => $this->id, "name" => $this->name]; // never the hash
}
}
echo json_encode(new User(1, "Ana", '$2y$10$abc'));
{"id":1,"name":"Ana"}
Enums and dates
A backed enum becomes its value. A DateTime becomes an object with date and timezone, which is rarely what you want. Format dates yourself:
<?php
enum Status: string { case Paid = "paid"; }
$order = [
"status" => Status::Paid,
"created" => (new DateTimeImmutable("2026-03-01 10:30:00", new DateTimeZone("UTC")))->format(DATE_ATOM),
];
echo json_encode($order);
{"status":"paid","created":"2026-03-01T10:30:00+00:00"}
Numbers
PHP floats may print with many digits. The setting serialize_precision = -1 (the default) gives the shortest exact form, so 0.1 stays 0.1.
Never encode secrets
Build the array from an allow-list of fields, so a password hash or token is never included by accident.
Pretty print in development only
JSON_PRETTY_PRINT is nice for humans, but sends more bytes. Use it for debugging and config files, not for API responses.