PHP JSON: преобразование данных, примеры и практические советы

Раздел: Разработка на PHP -> Форматы данных

Работа с JSON в PHP: кодирование и декодирование

Основным способом преобразования данных в формат JSON и обратно в PHP являются функции json_encode и json_decode. Они поддерживаются всеми современными версиями PHP и обеспечивают двустороннюю конвертацию между переменными PHP (массивами, объектами, скалярами) и строками JSON.

Как закодировать данные в JSON?


$data = ["name" => "Иван", "age" => 30, "skills" => ["PHP", "MySQL", "JavaScript"]];
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
echo $json;
{
    "name": "Иван",
    "age": 30,
    "skills": [
        "PHP",
        "MySQL",
        "JavaScript"
    ]
}

Флаг JSON_UNESCAPED_UNICODE сохраняет кириллицу без экранирования, а JSON_PRETTY_PRINT добавляет отступы для читаемости.

Как декодировать JSON строку в массив?


$jsonString = '{"name":"Иван","age":30,"skills":["PHP","MySQL","JavaScript"]}';
$array = json_decode($jsonString, true);
var_dump($array);
array(3) {
  ["name"]=>
  string(8) "Иван"
  ["age"]=>
  int(30)
  ["skills"]=>
  array(3) {
    [0]=>
    string(3) "PHP"
    [1]=>
    string(5) "MySQL"
    [2]=>
    string(10) "JavaScript"
  }
}

Второй аргумент true заставляет функцию возвращать ассоциативный массив, а не объект по умолчанию.

Типичные ошибки:

  • При использовании json_decode без проверки на null - функция возвращает null при ошибке, а также при значении JSON "null". Рекомендуется проверять json_last_error().
  • Кодировка строки должна быть UTF-8. Любые другие кодировки приведут к ошибке JSON_UNICODE_ERROR.
  • При кодировании объектов, не реализующих JsonSerializable, PHP преобразует только публичные свойства. Защищённые и приватные поля будут потеряны.

Альтернативные подходы и нюансы

Как сохранить читаемый JSON в файл?


$data = ['product' => 'Ноутбук', 'price' => 49999.99];
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
file_put_contents('product.json', $json);

Файл product.json будет содержать отформатированный JSON с отступами.

Как декодировать глубоко вложенный JSON с проверкой ошибок?


$json = file_get_contents('complex.json');
$result = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    $errorMsg = json_last_error_msg();
    // логирование или другая обработка ошибки
    exit("Ошибка декодирования: $errorMsg");
}
// работа с $result

Проблема: декодирование большого JSON может привести к переполнению памяти.

Решение: использовать потоковый JSON-парсер, например json_decode с ограничением глубины через флаг JSON_OBJECT_AS_ARRAY

Как закодировать объект с приватными полями?


class User implements JsonSerializable {
    private $name;
    private $age;
    
    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }
    
    public function jsonSerialize() {
        return [
            'name' => $this->name,
            'age' => $this->age
        ];
    }
}

$user = new User('Анна', 25);
echo json_encode($user, JSON_UNESCAPED_UNICODE);
{"name":"Анна","age":25}

Интерфейс JsonSerializable позволяет контролировать, какие данные будут включены в JSON.

Расширенные примеры кодирования и декодирования JSON

Пример 1: Кодирование с разными флагами

Пример

$data = [
    'company' => 'ООО "Ромашка"',
    'employees' => 150,
    'departments' => ['IT', 'HR', 'Sales'],
    'isActive' => true,
    'nullValue' => null
];

// Без флагов (экранирование Unicode, слэшей)
echo "Без флагов:\n";
echo json_encode($data) . "\n\n";

// С флагами для читаемости
$options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT;
echo "С читаемыми флагами:\n";
echo json_encode($data, $options);
Без флагов:
{"company":"\u041e\u041e\u041e \u0022\u0420\u043e\u043c\u0430\u0448\u043a\u0430\u0022","employees":150,"departments":["IT","HR","Sales"],"isActive":true,"nullValue":null}

С читаемыми флагами:
{
    "company": "ООО \"Ромашка\"",
    "employees": 150,
    "departments": [
        "IT",
        "HR",
        "Sales"
    ],
    "isActive": true,
    "nullValue": null
}

Пример 2: Декодирование в объект stdClass

Пример

$json = '{"title":"PHP 8","pages":450,"authors":["John","Jane"]}';
$obj = json_decode($json); // ассоциативный false по умолчанию
echo $obj->title . "\n";
echo $obj->authors[0];
PHP 8
John

Пример 3: Обработка ошибок декодирования

Пример

$badJson = '{"name": "Вася", age: 30}'; // ключ age не в кавычках
$decoded = json_decode($badJson);
if (json_last_error() !== JSON_ERROR_NONE) {
    $errorCode = json_last_error();
    $errorMsg = json_last_error_msg();
    echo "Код ошибки: $errorCode\n";
    echo "Сообщение: $errorMsg\n";
}
Код ошибки: 4
Сообщение: Syntax error, malformed JSON

Пример 4: Глубоко вложенный JSON и ограничение глубины

Пример

$deepJson = '{"a":{"b":{"c":{"d":"test"}}}}';
// По умолчанию глубина не ограничена (но ограничена памятью)
$decoded = json_decode($deepJson, true, 512, JSON_OBJECT_AS_ARRAY);
echo $decoded['a']['b']['c']['d']; // test

Пример 5: Кодирование объекта DateTime

Пример

$date = new DateTime('2025-01-15 14:30:00');
echo json_encode($date); // ошибка: object of class DateTime could not be converted to JSON
// Решение: преобразовать в строку или использовать JsonSerializable
class DateTimeWrapper implements JsonSerializable {
    private $datetime;
    public function __construct(DateTime $dt) {
        $this->datetime = $dt;
    }
    public function jsonSerialize() {
        return $this->datetime->format('Y-m-d H:i:s');
    }
}
$wrapper = new DateTimeWrapper(new DateTime('2025-01-15 14:30:00'));
echo json_encode($wrapper, JSON_UNESCAPED_UNICODE);
"2025-01-15 14:30:00"

Пример 6: Сериализация массива с нелатинскими ключами

Пример

$arr = ['ключ1' => 'значение1', 'ключ2' => 'значение2'];
echo json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
{"ключ1":"значение1","ключ2":"значение2"}

Флаг JSON_FORCE_OBJECT гарантирует, что пустой массив будет представлен как объект, а не как пустой массив.

Пример 7: Декодирование JSON с числовыми ключами

Пример

$json = '{"0":"a","1":"b","2":"c"}';
$arr = json_decode($json, true);
var_dump($arr);
array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
}

Пример 8: Потоковая обработка JSON (для больших файлов)

Пример

// Использование json_decode не подходит для очень больших файлов.
// Рекомендуется использовать специализированные парсеры, например, 
// расширение JSONCoder или библиотеку seld/jsonlint.
// Пример с базовым разбиением на чанки (упрощённо):
$handle = fopen('large.json', 'r');
$buffer = '';
while (!feof($handle)) {
    $buffer .= fread($handle, 8192);
    // здесь нужно парсить частично (требуется сторонняя реализация)
}
fclose($handle);

PHP JSON (кодирование/декодирование) - comments

En
Php json (php)