Полное руководство по использованию json_encode для преобразования данных в JSON в PHP
Основы и варианты использования json_encode
Функция json_encode преобразует переменные PHP в строку формата JSON. Основной синтаксис: json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false. Допустимые типы: строки, целые и дробные числа, булевы значения, null, массивы, объекты (публичные свойства). Ресурсы не поддерживаются.
<?php
$data = ['name' => 'Иван', 'age' => 30, 'skills' => ['PHP', 'JavaScript']];
$json = json_encode($data);
echo $json;
?>Php json encode (php: json_encode() - кодирование в json)
{"name":"\u0418\u0432\u0430\u043d","age":30,"skills":["PHP","JavaScript"]}Php данные в json (преобразование данных в json на php)
По умолчанию символы Unicode экранируются. Для управления форматом используются флаги.
Как закодировать кириллицу без экранирования?
Флаг JSON_UNESCAPED_UNICODE предотвращает экранирование многобайтовых символов.
<?php
$data = ['name' => 'Иван'];
echo json_encode($data, JSON_UNESCAPED_UNICODE);
?>{"name":"Иван"}Типичная ошибка: если строка не в UTF-8, json_encode вернет false. Решение: предварительно конвертировать в UTF-8 через mb_convert_encoding или установить правильную кодировку.
Как сделать читаемый формат JSON с отступами?
Флаг JSON_PRETTY_PRINT добавляет пробелы и переносы строк.
<?php
$data = ['a' => 1, 'b' => ['c' => 2]];
echo json_encode($data, JSON_PRETTY_PRINT);
?>{
"a": 1,
"b": {
"c": 2
}
}Для отладки удобно, но увеличивает объем данных. Не рекомендуется для продакшена.
Как принудительно получить объект вместо массива?
Флаг JSON_FORCE_OBJECT превращает даже пустой индексный массив в объект JSON.
<?php
$empty = [];
$indexed = ['a', 'b'];
echo json_encode($empty, JSON_FORCE_OBJECT);
echo "\n";
echo json_encode($indexed, JSON_FORCE_OBJECT);
?>{}
{"0":"a","1":"b"}Может нарушить ожидаемую структуру, если клиент ожидает массив.
Как обработать ошибки кодирования?
После вызова проверяем json_last_error() и json_last_error_msg().
<?php
$bad = "\xB1\x31"; // некорректный байт
$result = json_encode($bad);
if ($result === false) {
echo 'Ошибка: ' . json_last_error_msg();
}
?>Ошибка: Malformed UTF-8 characters, possibly incorrectly encoded
Кроме неверной кодировки возможны: JSON_ERROR_DEPTH (превышение глубины), JSON_ERROR_RECURSION (циклическая ссылка), JSON_ERROR_INF_OR_NAN (бесконечность или NaN). json_last_error следует вызывать только после json_encode.
Как закодировать объект собственного класса?
Реализовать интерфейс JsonSerializable и метод jsonSerialize().
<?php
class User implements JsonSerializable {
public $name;
protected $password;
public function __construct($name, $password) {
$this->name = $name;
$this->password = $password;
}
public function jsonSerialize() {
return [
'name' => $this->name,
'hasPassword' => !empty($this->password)
];
}
}
$user = new User('Alex', '123456');
echo json_encode($user);
?>{"name":"Alex","hasPassword":true}Без реализации JsonSerializable кодируются только public свойства. Приватные и защищенные игнорируются. Если объект содержит циклические ссылки, json_encode вернет false.
Как сохранить большие целые числа без потери точности?
Флаг JSON_BIGINT_AS_STRING кодирует числа как строки.
<?php
$big = 12345678901234567890;
echo json_encode($big); // Потеря точности
echo "\n";
echo json_encode($big, JSON_BIGINT_AS_STRING);
?>1.2345678901234568e+19 "12345678901234567890"
Если не использовать флаг, число может быть преобразовано в экспоненциальную форму с потерей точности. Для промышленных данных (ID, номера счетов) рекомендуется JSON_BIGINT_AS_STRING.
Расширенные примеры и нестандартные ситуации
Далее представлены более сложные сценарии использования json_encode с комбинированными флагами и обработкой граничных случаев.
Комбинация флагов: читаемый JSON с кириллицей
<?php
$data = ['title' => 'Привет, мир!', 'year' => 2023];
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
?>{
"title": "Привет, мир!",
"year": 2023
}Флаги комбинируются через побитовое ИЛИ.
Использование JSON_NUMERIC_CHECK
Автоматически преобразует строки, содержащие числа, в числовой тип.
<?php
$data = ['id' => '42', 'price' => '19.99'];
echo json_encode($data, JSON_NUMERIC_CHECK);
?>{"id":42,"price":19.99}Может привести к нежелательному изменению типов, если строки используются как идентификаторы (например, '001'). Следует применять осознанно.
Экранирование HTML символов
Для вставки JSON в HTML применяется комбинация флагов JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_HEX_APOS, чтобы экранировать <, >, &, " и '.
<?php
$html = '<script>alert("xss")</script>';
echo json_encode($html, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_HEX_APOS);
?>"\u003Cscript\u003Ealert(\u0022xss\u0022)\u003C\/script\u003E"
Это предотвращает XSS при вставке JSON в тег <script>.
Кодирование с частичным выводом при ошибке
Флаг JSON_PARTIAL_OUTPUT_ON_ERROR позволяет получить строку даже при наличии ошибок в части данных (например, некорректная строка заменяется на null).
<?php
$data = ['valid' => 'текст', 'bad' => "\xB1\x31"];
echo json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_UNICODE);
?>{"valid":"текст","bad":null}Не все ошибки могут быть проигнорированы, проверять json_last_error все равно стоит.
Ограничение глубины рекурсии
Параметр depth позволяет ограничить вложенность. Если превышено, возвращается false с ошибкой JSON_ERROR_DEPTH.
<?php
$deep = ['a' => ['b' => ['c' => 'd']]];
echo json_encode($deep, 0, 2); // depth=2, но вложенность 3
?>false
На практике глубину увеличивают, если структура действительно вложенная.
Кодирование с сохранением слешей
Флаг JSON_UNESCAPED_SLASHES не экранирует косую черту /, что полезно для URL.
<?php
$url = 'https://example.com/path/to/resource';
echo json_encode($url, JSON_UNESCAPED_SLASHES);
?>"https://example.com/path/to/resource"
Кодирование null, boolean и float
<?php
$values = [null, true, false, 3.14, 2.0];
echo json_encode($values, JSON_PRESERVE_ZERO_FRACTION);
?>[null,true,false,3.14,2.0]
Флаг JSON_PRESERVE_ZERO_FRACTION сохраняет числа с плавающей точкой в виде 2.0, а не 2.
Кодирование объектов с JsonSerializable с дополнительными параметрами
<?php
class Data implements JsonSerializable {
private $items = [];
public function add($item) {
$this->items[] = $item;
}
public function jsonSerialize() {
return ['count' => count($this->items), 'items' => $this->items];
}
}
$d = new Data();
$d->add('first');
echo json_encode($d, JSON_PRETTY_PRINT);
?>{
"count": 1,
"items": [
"first"
]
}