Avatar ·

Как красиво отформатировать JSON в PHP? Pretty-Print вывод

Всем привет! Я новичок в PHP и работаю над проектом, где нужно выводить JSON данные в читаемом виде. Проблема в том, что стандартный json_encode() выдает всё в одну строку, и это совершенно нечитаемо, особенно когда данные содержат вложенные массивы и объекты. Вот пример моего кода: ```php 'Иван Иванов', 'age' => 30, 'address' => array( 'city' => 'Москва', 'street' => 'Тверская', 'zip' => '101000' ), 'phones' => array( 'home' => '+7-495-123-45-67', 'mobile' => '+7-916-987-65-43' ), 'hobbies' => array('чтение', 'программирование', 'шахматы') ); $json = json_encode($data); echo $json; ?> ``` В результате я получаю что-то вроде: ```json {"name":"Иван Иванов","age":30,"address":{"city":"Москва","street":"Тверская","zip":"101000"},"phones":{"home":"+7-495-123-45-67","mobile":"+7-916-987-65-43"},"hobbies":["чтение","программирование","шахматы"]} ``` Это очень неудобно для отладки и для демонстрации данных пользователям. Я знаю, что должна быть возможность отформатировать JSON с отступами и переносами строк, но не могу найти правильный способ. Подскажите, пожалуйста, как сделать pretty-print для JSON в PHP? Буду благодарен за примеры кода! <<>>

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

В PHP начиная с версии 5.4 есть встроенная поддержка форматированного вывода JSON. Для этого нужно использовать константу JSON_PRETTY_PRINT в качестве второго аргумента функции json_encode(). Это самый простой и правильный способ.

<?php
$data = [
    'name' => 'Иван Иванов',
    'age' => 30,
    'address' => [
        'city' => 'Москва',
        'street' => 'Тверская',
        'zip' => '101000'
    ],
    'phones' => [
        'home' => '+7-495-123-45-67',
        'mobile' => '+7-916-987-65-43'
    ],
    'hobbies' => ['чтение', 'программирование', 'шахматы']
];

// Pretty-print с отступами в 4 пробела
$json = json_encode($data, JSON_PRETTY_PRINT);
echo $json;
?>

Результат будет выглядеть так:

{
    "name": "Иван Иванов",
    "age": 30,
    "address": {
        "city": "Москва",
        "street": "Тверская",
        "zip": "101000"
    },
    "phones": {
        "home": "+7-495-123-45-67",
        "mobile": "+7-916-987-65-43"
    },
    "hobbies": [
        "чтение",
        "программирование",
        "шахматы"
    ]
}

Дополнительные флаги для улучшения вывода

Вы можете комбинировать JSON_PRETTY_PRINT с другими флагами:

  • JSON_UNESCAPED_UNICODE — сохраняет кириллицу и другие Unicode-символы без экранирования (иначе русские буквы превратятся в \uXXXX)
  • JSON_UNESCAPED_SLASHES — не экранирует слеши (по умолчанию / превращается в \/)
  • JSON_NUMERIC_CHECK — преобразует строки, содержащие числа, в числовой тип
<?php
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
echo $json;
?>

Настройка глубины отступов

По умолчанию JSON_PRETTY_PRINT использует отступы в 4 пробела. Если вам нужно изменить это значение, можно использовать дополнительный параметр depth (доступен с PHP 7.1):

<?php
// Отступы в 2 пробела
$json = json_encode($data, JSON_PRETTY_PRINT, 2);
echo $json;
?>

Сохранение в файл с форматированием

Часто нужно сохранить отформатированный JSON в файл:

<?php
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
file_put_contents('data.json', $json);
echo "JSON сохранен в файл data.json";
?>

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

  • JSON_PRETTY_PRINT увеличивает размер вывода, поэтому не используйте его в production API, где важна производительность и минимальный размер данных
  • Для отладки и разработки это незаменимый инструмент
  • Если вы работаете с очень большими данными, форматирование может замедлить выполнение скрипта

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

<<>>

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

Если по каким-то причинам вы не можете использовать JSON_PRETTY_PRINT (например, работаете с устаревшей версией PHP < 5.4), можно реализовать форматирование вручную. Вот простой пример:

<?php
function prettyPrintJson($data, $indent = 0) {
    $result = '';
    $spaces = str_repeat('    ', $indent);
    
    if (is_array($data)) {
        // Определяем, ассоциативный массив или нет
        $isAssoc = array_keys($data) !== range(0, count($data) - 1);
        
        if ($isAssoc) {
            $result .= "{\n";
            $lastKey = array_key_last($data);
            foreach ($data as $key => $value) {
                $result .= $spaces . '    "' . $key . '": ' . prettyPrintJson($value, $indent + 1);
                if ($key !== $lastKey) $result .= ',';
                $result .= "\n";
            }
            $result .= $spaces . '}';
        } else {
            $result .= "[\n";
            $lastKey = count($data) - 1;
            foreach ($data as $i => $value) {
                $result .= $spaces . '    ' . prettyPrintJson($value, $indent + 1);
                if ($i !== $lastKey) $result .= ',';
                $result .= "\n";
            }
            $result .= $spaces . ']';
        }
    } else {
        $result .= json_encode($data);
    }
    
    return $result;
}

$data = ['name' => 'Иван', 'hobbies' => ['чтение', 'спорт']];
echo prettyPrintJson($data);
?>

Этот метод полезен для понимания логики форматирования, но на практике всегда используйте встроенную функцию — она быстрее, надёжнее и учитывает все краевые случаи (спецсимволы, вложенность, типы данных).

Также можно использовать сторонние библиотеки, например league/json-guard для валидации и форматирования, но для простого pretty-print встроенных средств PHP более чем достаточно.