Pretty-Printing JSON с PHP - PullRequest
       73

Pretty-Printing JSON с PHP

523 голосов
/ 19 мая 2011

Я создаю скрипт PHP, который передает данные JSON в другой скрипт.Мой скрипт строит данные в большой ассоциативный массив, а затем выводит данные, используя json_encode.Вот пример сценария:

$data = array('a' => 'apple', 'b' => 'banana', 'c' => 'catnip');
header('Content-type: text/javascript');
echo json_encode($data);

Приведенный выше код дает следующий вывод:

{"a":"apple","b":"banana","c":"catnip"}

Это здорово, если у вас небольшой объем данных, но я бы предпочелпо этим направлениям:

{
    "a": "apple",
    "b": "banana",
    "c": "catnip"
}

Есть ли способ сделать это в PHP без отвратительного взлома?Кажется, кто-то в Facebook понял это.

Ответы [ 21 ]

1014 голосов
/ 03 февраля 2012

PHP 5.4 предлагает опцию JSON_PRETTY_PRINT для использования с вызовом json_encode().

http://php.net/manual/en/function.json-encode.php

<?php
...
$json_string = json_encode($data, JSON_PRETTY_PRINT);
180 голосов
/ 19 марта 2012

Эта функция будет принимать строку JSON и делать отступ для очень удобного для чтения.Он также должен быть конвергентным,

prettyPrint( $json ) === prettyPrint( prettyPrint( $json ) )

Вход

{"key1":[1,2,3],"key2":"value"}

Выход

{
    "key1": [
        1,
        2,
        3
    ],
    "key2": "value"
}

Код

function prettyPrint( $json )
{
    $result = '';
    $level = 0;
    $in_quotes = false;
    $in_escape = false;
    $ends_line_level = NULL;
    $json_length = strlen( $json );

    for( $i = 0; $i < $json_length; $i++ ) {
        $char = $json[$i];
        $new_line_level = NULL;
        $post = "";
        if( $ends_line_level !== NULL ) {
            $new_line_level = $ends_line_level;
            $ends_line_level = NULL;
        }
        if ( $in_escape ) {
            $in_escape = false;
        } else if( $char === '"' ) {
            $in_quotes = !$in_quotes;
        } else if( ! $in_quotes ) {
            switch( $char ) {
                case '}': case ']':
                    $level--;
                    $ends_line_level = NULL;
                    $new_line_level = $level;
                    break;

                case '{': case '[':
                    $level++;
                case ',':
                    $ends_line_level = $level;
                    break;

                case ':':
                    $post = " ";
                    break;

                case " ": case "\t": case "\n": case "\r":
                    $char = "";
                    $ends_line_level = $new_line_level;
                    $new_line_level = NULL;
                    break;
            }
        } else if ( $char === '\\' ) {
            $in_escape = true;
        }
        if( $new_line_level !== NULL ) {
            $result .= "\n".str_repeat( "\t", $new_line_level );
        }
        $result .= $char.$post;
    }

    return $result;
}
67 голосов
/ 27 июля 2016

Многие пользователи предложили вам использовать

echo json_encode($results, JSON_PRETTY_PRINT);

Что абсолютно верно.Но этого недостаточно, браузер должен понимать тип данных, вы можете указать заголовок непосредственно перед передачей данных пользователю.

header('Content-Type: application/json');

Это приведет к хорошо отформатированному выводу.

Или, если вам нравятся расширения, вы можете использовать JSONView for Chrome.

40 голосов
/ 19 мая 2011

У меня была такая же проблема.

В любом случае, я просто использовал код форматирования json:

http://recursive -design.com / блог / 2008/03/11 / форматно-JSON-с PHP /

Хорошо работает для того, для чего мне это было нужно.

И более поддерживаемая версия: https://github.com/GerHobbelt/nicejson-php

23 голосов
/ 20 октября 2015

Я понимаю, что этот вопрос задает вопрос о том, как кодировать ассоциативный массив в довольно отформатированную строку JSON, так что это не дает прямого ответа на вопрос, но если у вас есть строка в формате JSON, вы можете сделатьон довольно просто декодируется и перекодируется (требуется PHP> = 5.4):

$json = json_encode(json_decode($json), JSON_PRETTY_PRINT);

Пример:

header('Content-Type: application/json');
$json_ugly = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
$json_pretty = json_encode(json_decode($json_ugly), JSON_PRETTY_PRINT);
echo $json_pretty;

Это выводит:

{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4,
    "e": 5
}
11 голосов
/ 26 октября 2018

Склейка нескольких ответов соответствует моей потребности в существующем json:

<code>Code:
echo "<pre>"; 
echo json_encode(json_decode($json_response), JSON_PRETTY_PRINT); 
echo "
"; Вывод: {" data ": {" token_type ":" bearer "," expires_in ": 3628799,"scopes": "full_access", "creation_at": 1540504324}, "errors": [], "pagination": {}, "token_type": "bearer", "expires_in": 3628799, "scopes": "full_access", "creation_at": 1540504324}
10 голосов
/ 19 мая 2011

Если вы используете Firefox, установите JSONovich . Я знаю, что это не совсем PHP-решение, но оно подходит для целей разработки / отладки.

10 голосов
/ 16 января 2014

Я взял код от Composer: https://github.com/composer/composer/blob/master/src/Composer/Json/JsonFile.php и nicejson: https://github.com/GerHobbelt/nicejson-php/blob/master/nicejson.php Код Composer хорош, потому что он свободно обновляется с 5.3 до 5.4, но кодирует только объект, тогда как nicejson принимает строки json, поэтому я объединил их. Код можно использовать для форматирования строки json и / или кодирования объектов, в настоящее время я использую его в модуле Drupal.

if (!defined('JSON_UNESCAPED_SLASHES'))
    define('JSON_UNESCAPED_SLASHES', 64);
if (!defined('JSON_PRETTY_PRINT'))
    define('JSON_PRETTY_PRINT', 128);
if (!defined('JSON_UNESCAPED_UNICODE'))
    define('JSON_UNESCAPED_UNICODE', 256);

function _json_encode($data, $options = 448)
{
    if (version_compare(PHP_VERSION, '5.4', '>='))
    {
        return json_encode($data, $options);
    }

    return _json_format(json_encode($data), $options);
}

function _pretty_print_json($json)
{
    return _json_format($json, JSON_PRETTY_PRINT);
}

function _json_format($json, $options = 448)
{
    $prettyPrint = (bool) ($options & JSON_PRETTY_PRINT);
    $unescapeUnicode = (bool) ($options & JSON_UNESCAPED_UNICODE);
    $unescapeSlashes = (bool) ($options & JSON_UNESCAPED_SLASHES);

    if (!$prettyPrint && !$unescapeUnicode && !$unescapeSlashes)
    {
        return $json;
    }

    $result = '';
    $pos = 0;
    $strLen = strlen($json);
    $indentStr = ' ';
    $newLine = "\n";
    $outOfQuotes = true;
    $buffer = '';
    $noescape = true;

    for ($i = 0; $i < $strLen; $i++)
    {
        // Grab the next character in the string
        $char = substr($json, $i, 1);

        // Are we inside a quoted string?
        if ('"' === $char && $noescape)
        {
            $outOfQuotes = !$outOfQuotes;
        }

        if (!$outOfQuotes)
        {
            $buffer .= $char;
            $noescape = '\\' === $char ? !$noescape : true;
            continue;
        }
        elseif ('' !== $buffer)
        {
            if ($unescapeSlashes)
            {
                $buffer = str_replace('\\/', '/', $buffer);
            }

            if ($unescapeUnicode && function_exists('mb_convert_encoding'))
            {
                // /1715980/kak-dekodirovat-escape-posledovatelnosti-unicode-takie-kak-u00ed-v-sootvetstvuyschie-simvoly-v-kodirovke-utf-8
                $buffer = preg_replace_callback('/\\\\u([0-9a-f]{4})/i',
                    function ($match)
                    {
                        return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
                    }, $buffer);
            } 

            $result .= $buffer . $char;
            $buffer = '';
            continue;
        }
        elseif(false !== strpos(" \t\r\n", $char))
        {
            continue;
        }

        if (':' === $char)
        {
            // Add a space after the : character
            $char .= ' ';
        }
        elseif (('}' === $char || ']' === $char))
        {
            $pos--;
            $prevChar = substr($json, $i - 1, 1);

            if ('{' !== $prevChar && '[' !== $prevChar)
            {
                // If this character is the end of an element,
                // output a new line and indent the next line
                $result .= $newLine;
                for ($j = 0; $j < $pos; $j++)
                {
                    $result .= $indentStr;
                }
            }
            else
            {
                // Collapse empty {} and []
                $result = rtrim($result) . "\n\n" . $indentStr;
            }
        }

        $result .= $char;

        // If the last character was the beginning of an element,
        // output a new line and indent the next line
        if (',' === $char || '{' === $char || '[' === $char)
        {
            $result .= $newLine;

            if ('{' === $char || '[' === $char)
            {
                $pos++;
            }

            for ($j = 0; $j < $pos; $j++)
            {
                $result .= $indentStr;
            }
        }
    }
    // If buffer not empty after formating we have an unclosed quote
    if (strlen($buffer) > 0)
    {
        //json is incorrectly formatted
        $result = false;
    }

    return $result;
}
6 голосов
/ 18 сентября 2017

Если у вас есть JSON ($ugly_json)

echo nl2br(str_replace(' ', '&nbsp;', (json_encode(json_decode($ugly_json), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES))));
6 голосов
/ 28 апреля 2016

Используйте <pre> в сочетании с json_encode() и опцией JSON_PRETTY_PRINT:

<code><pre>
    <?php
    echo json_encode($dataArray, JSON_PRETTY_PRINT);
    ?>
...