Avatar ·

PHP: Как красиво отформатировать JSON (Pretty-Print) для вывода на экран и в файл?

Всем привет! Я новичок в PHP и работаю над небольшим проектом, где нужно выводить данные в формате JSON на экран и сохранять их в лог-файл. Сейчас я использую функцию json_encode(), но она выдает всё одной строкой — это очень неудобно читать, особенно когда данные сложные и вложенные. Вот мой текущий код: ```php [ 'name' => 'Иван', 'email' => 'ivan@example.com', 'age' => 30, 'hobbies' => ['рыбалка', 'программирование', 'чтение'] ], 'status' => 'active', 'last_login' => '2023-10-15 14:30:00' ]; $json = json_encode($data); echo $json; // Сохраняем в файл file_put_contents('log.json', $json); ?> ``` На выходе получается каша вроде: `{"user":{"name":"Иван","email":"ivan@example.com","age":30,"hobbies":["рыбалка","программирование","чтение"]},"status":"active","last_login":"2023-10-15 14:30:00"}` Я слышал, что есть какой-то "pretty print" для JSON в PHP. Подскажите, как сделать так, чтобы JSON выводился с отступами, переносами строк и был читабельным? Нужно решение и для вывода в браузер (чтобы код был красивым), и для записи в файл. Заранее спасибо за помощь! <<>>

Решение: используем флаг JSON_PRETTY_PRINT

В PHP есть встроенная поддержка "pretty-printing" (красивого форматирования) JSON. Всё, что нужно — это добавить второй параметр JSON_PRETTY_PRINT к функции json_encode(). Этот флаг автоматически расставит отступы и переносы строк.

Базовый пример

<?php
$data = [
    'user' => [
        'name' => 'Иван',
        'email' => 'ivan@example.com',
        'age' => 30,
        'hobbies' => ['рыбалка', 'программирование', 'чтение']
    ],
    'status' => 'active',
    'last_login' => '2023-10-15 14:30:00'
];

// Красивое форматирование
$json = json_encode($data, JSON_PRETTY_PRINT);
echo $json;
?>

Теперь вывод будет выглядеть так:

{
    "user": {
        "name": "Иван",
        "email": "ivan@example.com",
        "age": 30,
        "hobbies": [
            "рыбалка",
            "программирование",
            "чтение"
        ]
    },
    "status": "active",
    "last_login": "2023-10-15 14:30:00"
}

Запись в файл с форматированием

Для сохранения в файл используем тот же подход:

<?php
$json = json_encode($data, JSON_PRETTY_PRINT);
file_put_contents('log.json', $json);
echo 'JSON успешно сохранён в файл с форматированием!';
?>

Дополнительные полезные флаги

Часто JSON_PRETTY_PRINT комбинируют с другими флагами для лучшего результата:

  • JSON_UNESCAPED_UNICODE — сохраняет кириллицу и другие Unicode-символы как есть (без \uXXXX). Очень важно для русского языка!
  • JSON_UNESCAPED_SLASHES — не экранирует слеши (/). Полезно для URL.
  • JSON_NUMERIC_CHECK — преобразует строки, содержащие числа, в числовой тип.

Полный пример с кириллицей

<?php
$data = [
    'title' => 'Привет, мир!',
    'url' => 'https://example.com/api/data',
    'count' => '42' // строка, но можно преобразовать в число
];

$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
echo $json;
?>

Результат:

{
    "title": "Привет, мир!",
    "url": "https://example.com/api/data",
    "count": 42
}

Вывод в браузер с правильным заголовком

Если вы выводите JSON напрямую в браузер (не в HTML-страницу), установите правильный Content-Type:

<?php
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>

Важные замечания

  • JSON_PRETTY_PRINT доступен в PHP 5.4.0 и выше.
  • Не используйте pretty-print для production API, если клиент не просит — это увеличивает размер ответа. Обычно API отдают компактный JSON.
  • Для отладки pretty-print незаменим: вы сразу видите структуру данных.

Используйте эти простые решения, и ваш JSON всегда будет читабельным!

<<>>

Альтернативный подход: ручное форматирование с помощью рекурсии

Если по каким-то причинам вы не можете использовать JSON_PRETTY_PRINT (например, очень старая версия PHP), можно написать свою функцию для форматирования. Но на практике это редко нужно — лучше обновить PHP.

Вот пример простой рекурсивной функции, которая делает то же самое:

<?php
function prettyPrintJson($data, $indent = 0) {
    $output = '';
    $spaces = str_repeat('  ', $indent);
    
    if (is_array($data)) {
        // Проверяем, ассоциативный массив или обычный
        if (array_keys($data) !== range(0, count($data) - 1)) {
            // Ассоциативный (объект)
            $output .= "{\n";
            $lastKey = array_key_last($data);
            foreach ($data as $key => $value) {
                $output .= $spaces . '  "' . $key . '": ' . prettyPrintJson($value, $indent + 1);
                if ($key !== $lastKey) $output .= ',';
                $output .= "\n";
            }
            $output .= $spaces . '}';
        } else {
            // Обычный массив
            $output .= "[\n";
            foreach ($data as $index => $value) {
                $output .= $spaces . '  ' . prettyPrintJson($value, $indent + 1);
                if ($index !== count($data) - 1) $output .= ',';
                $output .= "\n";
            }
            $output .= $spaces . ']';
        }
    } else {
        // Строка, число, bool или null
        if (is_string($data)) {
            $output .= '"' . addslashes($data) . '"';
        } elseif (is_bool($data)) {
            $output .= $data ? 'true' : 'false';
        } elseif (is_null($data)) {
            $output .= 'null';
        } else {
            $output .= $data;
        }
    }
    
    return $output;
}

$data = ['name' => 'Тест', 'items' => [1, 2, 3]];
echo prettyPrintJson($data);
?>

Минусы ручного подхода:

  • Код сложнее и подвержен ошибкам (например, экранирование спецсимволов в строках).
  • Не учитывает все тонкости JSON (float, big integers, управляющие символы).
  • Работает медленнее, чем встроенная функция.

Вывод: Всегда используйте JSON_PRETTY_PRINT. Если его нет — обновите PHP до версии 5.4.0 или выше. Это стандарт индустрии.