616 votos

Pretty-Printing JSON con PHP

Estoy construyendo un script de PHP que se alimenta de datos JSON a otro script. Mi script se basa de datos en una gran matriz asociativa, y, a continuación, envía los datos utilizando json_encode. Aquí hay un ejemplo de script:

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

El código anterior produce la siguiente salida:

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

Esto es grande si usted tiene una pequeña cantidad de datos, pero preferiría algo a lo largo de estas líneas:

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

Hay una forma de hacer esto en PHP sin un feo hack? Parece que alguien en Facebook imaginé.

1188voto

countfloortiles Puntos 2537

PHP 5.4 ofrece el JSON_PRETTY_PRINT opción para su uso con el json_encode() llamar.

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

<?php
...
$json_string = json_encode($data, JSON_PRETTY_PRINT);

189voto

Kendall Hopkins Puntos 12193

Esta función tomará cadena JSON y lo muy legible guión. También debería ser convergente,

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

Entrada

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

Salida

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

Código

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;
}

41voto

Jason Puntos 5421

Tuve el mismo problema.

De todos modos yo usé el json formato código aquí:

http://recursive-Design.com/blog/2008/03/11/Format-JSON-with-PHP/

Funciona bien para lo que necesitaba para.

Y una versión más mantenimiento: https://github.com/GerHobbelt/nicejson-php

11voto

ulk200 Puntos 51

Tomé el código del Compositor : https://github.com/composer/composer/blob/master/src/Composer/Json/JsonFile.php y nicejson : https://github.com/GerHobbelt/nicejson-php/blob/master/nicejson.php Compositor de código es bueno, porque actualiza con fluidez de 5.3 a 5.4 pero sólo codifica objeto mientras que nicejson toma las cadenas json, así que he fusionado. El código puede ser utilizado para el formato de cadena json y/o codificar los objetos, en la actualidad estoy utilizando en un módulo de 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'))
            {
                // http://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha
                $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;
}

10voto

Jay Sidri Puntos 3447

Si estás en firefox instalar JSONovich. Realmente no sé que una solución PHP, pero lo hace el truco para propósitos de desarrollo/depuración.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X