Pretty-Printing JSON con PHP


589

Estoy creando un script PHP que alimenta datos JSON a otro script. Mi script crea datos en una gran matriz asociativa y luego genera los datos usando json_encode. Aquí hay un script de ejemplo:

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

El código anterior produce el siguiente resultado:

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

Esto es genial si tiene una pequeña cantidad de datos, pero preferiría algo en este sentido:

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

¿Hay alguna manera de hacer esto en PHP sin un truco feo? Parece que alguien en Facebook lo descubrió.


26
Para PHP anterior a 5.4, puede usar el respaldo en upgradephp comoup_json_encode($data, JSON_PRETTY_PRINT);
mario

66
uso del encabezado ('Tipo de contenido: aplicación / json'); hace que el navegador sea bastante impreso
partho

44
A partir de Juy 2018, solo enviando el Content-Type: application/jsonencabezado Firefox mostrará el resultado usando su propio analizador JSON interno, mientras que Chrome muestra el texto sin formato. +1 Firefox!
andreszs

Respuestas:


1127

PHP 5.4 ofrece la JSON_PRETTY_PRINTopción de usar con la json_encode()llamada.

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

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

33
Gracias, esta es la mejor manera de hacerlo ahora. Sin embargo, no tenía PHP 5.4 cuando hice esta pregunta ...
Zach Rattner

99
5.5.3 aquí, solo parece agregar un poco de espacio entre los caracteres, no ninguna sangría real.

35
Se supone que JSON no contiene saltos de línea HTML, mientras que los caracteres de nueva línea son válidos en JSON. Si desea mostrar JSON en una página web, realice un reemplazo de cadena en los caracteres de nueva línea o coloque el JSON en un elemento <pre> ... </pre>. Ver json.org para la referencia de sintaxis.
ekillaby

13
No se olvide de respuesta ajustado Content-Typea application/jsonsi desea que el navegador para visualizar JSON bastante bien impresa.
Pijusn

66
@countfloortiles no funcionará directamente, debe incluir su salida en la <pre>etiqueta como<?php ... $json_string = json_encode($data, JSON_PRETTY_PRINT); echo "<pre>".$json_string."<pre>";
Salman Mohammad

187

Esta función tomará una cadena JSON y la sangrará de forma muy legible. 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;
}

84

Muchos usuarios sugirieron que usaras

echo json_encode($results, JSON_PRETTY_PRINT);

Lo cual es absolutamente correcto. Pero no es suficiente, el navegador necesita comprender el tipo de datos, puede especificar el encabezado justo antes de hacer eco de los datos al usuario.

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

Esto dará como resultado una salida bien formateada.

O, si le gustan las extensiones, puede usar JSONView para Chrome.


3
Solo configure el encabezado y Firefox lo mostrará perfectamente usando su propio analizador interno de depuración JSON, ¡no es necesario tocar el contenido JSON en absoluto! ¡¡Gracias!!
andreszs

1
Funciona en cromo también. Gracias.
Don Dilanga

41

Tuve el mismo problema.

De todos modos, acabo de usar el código de formato json aquí:

http://recursive-design.com/blog/2008/03/11/format-json-with-php/

Funciona bien para lo que lo necesitaba.

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



1
Si está en PHP7.0 (y superior) y todavía necesita imprimir JSON con sangría personalizada, localheinz.com/blog/2018/01/04/… debería ayudar.
localheinz

40

Me doy cuenta de que esta pregunta es sobre cómo codificar una matriz asociativa en una cadena JSON con un formato bonito, por lo que esto no responde directamente a la pregunta, pero si tiene una cadena que ya está en formato JSON, puede hacerlo bastante simple decodificándolo y volviéndolo a codificar (requiere PHP> = 5.4):

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

Ejemplo:

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;

Esto produce:

{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4,
    "e": 5
}

gracias, solo funciona si agrego esto en la parte superior del bloque php ... header ('Content-Type: application / json');
DeyaEldeen

2
@DeyaEldeen Si no usa ese encabezado, PHP le dirá al navegador que está enviando HTML, por lo que debería ver la fuente de la página para ver la cadena JSON formateada. Supuse que se entendía, pero supongo que no. Lo he agregado a mi respuesta.
Mike

Y cualquiera que esté siguiendo / revisando un registro / archivo en el shell de Unix / Linux, ¡esta es la solución aquí! ¡Bien cuidado, @ Mike, hace que sea fácil de leer!
fusion27

@ fusion27 No estoy realmente seguro de a qué archivos de registro se refiere. Nunca he oído hablar de ningún programa que registre algo en JSON.
Mike

@ Mike, es un PHP rápido y sucio que agregué agregando el cuerpo de la solicitud (que es una cadena JSON serializada) PUBLICADO en mi PHP en un archivo de texto, luego lo sigo en el shell de Unix para poder ver POST en vivo. Estoy usando tu truco para formatear ese JSON haciendo que el archivo de texto sea mucho más útil.
fusion27

25

Pegar varias respuestas juntas se ajusta a mi necesidad de json existente:

Code:
echo "<pre>"; 
echo json_encode(json_decode($json_response), JSON_PRETTY_PRINT); 
echo "</pre>";

Output:
{
    "data": {
        "token_type": "bearer",
        "expires_in": 3628799,
        "scopes": "full_access",
        "created_at": 1540504324
    },
    "errors": [],
    "pagination": {},
    "token_type": "bearer",
    "expires_in": 3628799,
    "scopes": "full_access",
    "created_at": 1540504324
}

3
Aquí hay una pequeña función de envoltura para hacer esto:function json_print($json) { return '<pre>' . json_encode(json_decode($json), JSON_PRETTY_PRINT) . '</pre>'; }
Danny Beckett

11

Tomé el código de Composer: https://github.com/composer/composer/blob/master/src/Composer/Json/JsonFile.php y nicejson: https://github.com/GerHobbelt/nicejson-php/blob /master/nicejson.php El código del compositor es bueno porque se actualiza con fluidez de 5.3 a 5.4 pero solo codifica objetos, mientras que nicejson toma cadenas json, así que las fusioné. El código se puede usar para formatear cadenas json y / o codificar objetos, actualmente lo estoy usando en un módulo 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;
}

¡Así es como se hace! La implementación propia solo se ejecuta si nativo no está disponible. Si está seguro de que su código solo se ejecutará en PHP 5.4 o superior, puede descansar en JSON_PRETTY_PRINT
Heroselohim

Esta solución me da un error (error de análisis: error de sintaxis, T_FUNCTION inesperado) en la función de línea ($ match)
ARLabs


10

Si está en Firefox, instale JSONovich . No conozco realmente una solución PHP, pero sirve para propósitos de desarrollo / depuración.


3
Creo que esta es la solución adecuada para cuando se desarrolla una API. Ofrece lo mejor de ambos mundos, una depuración fácil ya que puede leer todo y no está alterando el comportamiento del backends, incluido su rendimiento.
Daniel

De acuerdo, está muy bien formateado con colores y también es plegable. Mucho mejor de lo que podrías esperar con un poco de PHP
Matthew Lock

10

He usado esto:

echo "<pre>".json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."</pre>";

O use encabezados php como a continuación:

header('Content-type: application/json; charset=UTF-8');
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

8

Manera simple para php> 5.4: me gusta en el gráfico de Facebook

$Data = array('a' => 'apple', 'b' => 'banana', 'c' => 'catnip');
$json= json_encode($Data, JSON_PRETTY_PRINT);
header('Content-Type: application/json');
print_r($json);

Resultado en el navegador

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

@Madbreaks, se imprime bien en el archivo php, no es necesario escribir en el archivo json, al igual que Facebook.
dknepa

6

Usar <pre>en combinación con json_encode()y la JSON_PRETTY_PRINTopción:

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

6

Si tiene JSON existente ( $ugly_json)

echo nl2br(str_replace(' ', '&nbsp;', (json_encode(json_decode($ugly_json), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES))));

5

Tener salida completa de color: solución pequeña

Código:

$s = '{"access": {"token": {"issued_at": "2008-08-16T14:10:31.309353", "expires": "2008-08-17T14:10:31Z", "id": "MIICQgYJKoZIhvcIegeyJpc3N1ZWRfYXQiOiAi"}, "serviceCatalog": [], "user": {"username": "ajay", "roles_links": [], "id": "16452ca89", "roles": [], "name": "ajay"}}}';

$crl = 0;
$ss = false;
echo "<pre>";
for($c=0; $c<strlen($s); $c++)
{
    if ( $s[$c] == '}' || $s[$c] == ']' )
    {
        $crl--;
        echo "\n";
        echo str_repeat(' ', ($crl*2));
    }
    if ( $s[$c] == '"' && ($s[$c-1] == ',' || $s[$c-2] == ',') )
    {
        echo "\n";
        echo str_repeat(' ', ($crl*2));
    }
    if ( $s[$c] == '"' && !$ss )
    {
        if ( $s[$c-1] == ':' || $s[$c-2] == ':' )
            echo '<span style="color:#0000ff;">';
        else
            echo '<span style="color:#ff0000;">';
    }
    echo $s[$c];
    if ( $s[$c] == '"' && $ss )
        echo '</span>';
    if ( $s[$c] == '"' )
          $ss = !$ss;
    if ( $s[$c] == '{' || $s[$c] == '[' )
    {
        $crl++;
        echo "\n";
        echo str_repeat(' ', ($crl*2));
    }
}
echo $s[$c];

Esto fue muy útil, a pesar de que tenía algunos errores. Los arreglé y ahora funciona de maravilla, ¡y la función no es tan grande en absoluto! gracias Ajay
Daniel

solo para comentar las correcciones si alguien quiere usar esto ... agregue una verificación de validación $ c> 1 en la segunda y tercera condición if, y el último eco lo envuelve en un is_array ($ s) if. eso debería cubrirlo y no debería obtener ningún error de desplazamiento de cadena sin inicializar.
Daniel

5

Puede modificar un poco la respuesta de Kendall Hopkins en la declaración de cambio para obtener una impresión bastante limpia y agradablemente sangrada pasando una cadena json en lo siguiente:

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;
                $char.="<br>";
                for($index=0;$index<$level-1;$index++){$char.="-----";}
                break;

            case '{': case '[':
                $level++;
                $char.="<br>";
                for($index=0;$index<$level;$index++){$char.="-----";}
                break;
            case ',':
                $ends_line_level = $level;
                $char.="<br>";
                for($index=0;$index<$level;$index++){$char.="-----";}
                break;

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

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

echo "RESULTS ARE: <br><br>$result";
return $result;

}

Ahora solo ejecute la función prettyPrint ($ your_json_string); en línea en su php y disfrute de la impresión. Si eres minimalista y, por algún motivo, no te gustan los corchetes, puedes deshacerte de ellos fácilmente reemplazándolos $char.="<br>";con $char="<br>";en los tres casos principales de cambio en $ char. Esto es lo que obtienes por una llamada a la API de Google Maps para la ciudad de Calgary

RESULTS ARE: 

{
- - - "results" : [
- - -- - - {
- - -- - -- - - "address_components" : [
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Calgary"
- - -- - -- - -- - -- - - "short_name" : "Calgary"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "locality"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Division No. 6"
- - -- - -- - -- - -- - - "short_name" : "Division No. 6"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "administrative_area_level_2"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Alberta"
- - -- - -- - -- - -- - - "short_name" : "AB"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "administrative_area_level_1"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Canada"
- - -- - -- - -- - -- - - "short_name" : "CA"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "country"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - - ]
- - -- - -
- - -- - -- - - "formatted_address" : "Calgary, AB, Canada"
- - -- - -- - - "geometry" : {
- - -- - -- - -- - - "bounds" : {
- - -- - -- - -- - -- - - "northeast" : {
- - -- - -- - -- - -- - -- - - "lat" : 51.18383
- - -- - -- - -- - -- - -- - - "lng" : -113.8769511 }
- - -- - -- - -- - -
- - -- - -- - -- - -- - - "southwest" : {
- - -- - -- - -- - -- - -- - - "lat" : 50.84240399999999
- - -- - -- - -- - -- - -- - - "lng" : -114.27136 }
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - "location" : {
- - -- - -- - -- - -- - - "lat" : 51.0486151
- - -- - -- - -- - -- - - "lng" : -114.0708459 }
- - -- - -- - -
- - -- - -- - -- - - "location_type" : "APPROXIMATE"
- - -- - -- - -- - - "viewport" : {
- - -- - -- - -- - -- - - "northeast" : {
- - -- - -- - -- - -- - -- - - "lat" : 51.18383
- - -- - -- - -- - -- - -- - - "lng" : -113.8769511 }
- - -- - -- - -- - -
- - -- - -- - -- - -- - - "southwest" : {
- - -- - -- - -- - -- - -- - - "lat" : 50.84240399999999
- - -- - -- - -- - -- - -- - - "lng" : -114.27136 }
- - -- - -- - -- - - }
- - -- - -- - - }
- - -- - -
- - -- - -- - - "place_id" : "ChIJ1T-EnwNwcVMROrZStrE7bSY"
- - -- - -- - - "types" : [
- - -- - -- - -- - - "locality"
- - -- - -- - -- - - "political" ]
- - -- - - }
- - - ]

- - - "status" : "OK" }

Esto es realmente agradable, gracias. Una cosa que creo para agregar una ligera mejora es usar una var para: $ indent = "-----", luego usar eso (en lugar de "-----" en diferentes lugares del código)
gvanto

3

Podrías hacerlo como a continuación.

$array = array(
   "a" => "apple",
   "b" => "banana",
   "c" => "catnip"
);

foreach ($array as $a_key => $a_val) {
   $json .= "\"{$a_key}\" : \"{$a_val}\",\n";
}

header('Content-Type: application/json');
echo "{\n"  .rtrim($json, ",\n") . "\n}";

Lo anterior generaría una especie de me gusta en Facebook.

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

¿Qué pasa si a_vales una matriz o un objeto?
Zach Rattner

1
Respondí un ejemplo usando el Json en la pregunta, actualizaré mi respuesta pronto.
Jake

3

Caso clásico para una solución recursiva. Aquí está el mío:

class JsonFormatter {
    public static function prettyPrint(&$j, $indentor = "\t", $indent = "") {
        $inString = $escaped = false;
        $result = $indent;

        if(is_string($j)) {
            $bak = $j;
            $j = str_split(trim($j, '"'));
        }

        while(count($j)) {
            $c = array_shift($j);
            if(false !== strpos("{[,]}", $c)) {
                if($inString) {
                    $result .= $c;
                } else if($c == '{' || $c == '[') {
                    $result .= $c."\n";
                    $result .= self::prettyPrint($j, $indentor, $indentor.$indent);
                    $result .= $indent.array_shift($j);
                } else if($c == '}' || $c == ']') {
                    array_unshift($j, $c);
                    $result .= "\n";
                    return $result;
                } else {
                    $result .= $c."\n".$indent;
                } 
            } else {
                $result .= $c;
                $c == '"' && !$escaped && $inString = !$inString;
                $escaped = $c == '\\' ? !$escaped : false;
            }
        }

        $j = $bak;
        return $result;
    }
}

Uso:

php > require 'JsonFormatter.php';
php > $a = array('foo' => 1, 'bar' => 'This "is" bar', 'baz' => array('a' => 1, 'b' => 2, 'c' => '"3"'));
php > print_r($a);
Array
(
    [foo] => 1
    [bar] => This "is" bar
    [baz] => Array
        (
            [a] => 1
            [b] => 2
            [c] => "3"
        )

)
php > echo JsonFormatter::prettyPrint(json_encode($a));
{
    "foo":1,
    "bar":"This \"is\" bar",
    "baz":{
        "a":1,
        "b":2,
        "c":"\"3\""
    }
}

Salud


3

Esta solución hace que JSON sea 'realmente bonito'. No es exactamente lo que pedía el OP, pero le permite visualizar mejor el JSON.

/**
 * takes an object parameter and returns the pretty json format.
 * this is a space saving version that uses 2 spaces instead of the regular 4
 *
 * @param $in
 *
 * @return string
 */
function pretty_json ($in): string
{
  return preg_replace_callback('/^ +/m',
    function (array $matches): string
    {
      return str_repeat(' ', strlen($matches[0]) / 2);
    }, json_encode($in, JSON_PRETTY_PRINT | JSON_HEX_APOS)
  );
}

/**
 * takes a JSON string an adds colours to the keys/values
 * if the string is not JSON then it is returned unaltered.
 *
 * @param string $in
 *
 * @return string
 */

function markup_json (string $in): string
{
  $string  = 'green';
  $number  = 'darkorange';
  $null    = 'magenta';
  $key     = 'red';
  $pattern = '/("(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/';
  return preg_replace_callback($pattern,
      function (array $matches) use ($string, $number, $null, $key): string
      {
        $match  = $matches[0];
        $colour = $number;
        if (preg_match('/^"/', $match))
        {
          $colour = preg_match('/:$/', $match)
            ? $key
            : $string;
        }
        elseif ($match === 'null')
        {
          $colour = $null;
        }
        return "<span style='color:{$colour}'>{$match}</span>";
      }, str_replace(['<', '>', '&'], ['&lt;', '&gt;', '&amp;'], $in)
   ) ?? $in;
}

public function test_pretty_json_object ()
{
  $ob       = new \stdClass();
  $ob->test = 'unit-tester';
  $json     = pretty_json($ob);
  $expected = <<<JSON
{
  "test": "unit-tester"
}
JSON;
  $this->assertEquals($expected, $json);
}

public function test_pretty_json_str ()
{
  $ob   = 'unit-tester';
  $json = pretty_json($ob);
  $this->assertEquals("\"$ob\"", $json);
}

public function test_markup_json ()
{
  $json = <<<JSON
[{"name":"abc","id":123,"warnings":[],"errors":null},{"name":"abc"}]
JSON;
  $expected = <<<STR
[
  {
    <span style='color:red'>"name":</span> <span style='color:green'>"abc"</span>,
    <span style='color:red'>"id":</span> <span style='color:darkorange'>123</span>,
    <span style='color:red'>"warnings":</span> [],
    <span style='color:red'>"errors":</span> <span style='color:magenta'>null</span>
  },
  {
    <span style='color:red'>"name":</span> <span style='color:green'>"abc"</span>
  }
]
STR;

  $output = markup_json(pretty_json(json_decode($json)));
  $this->assertEquals($expected,$output);
}

}


2

Si solo usó $json_string = json_encode($data, JSON_PRETTY_PRINT);, obtendrá en el navegador algo como esto (usando el enlace de Facebook de la pregunta :)): ingrese la descripción de la imagen aquí

pero si usó una extensión de Chrome como JSONView (incluso sin la opción de PHP anterior), obtendrá una solución depurable más legible donde incluso puede plegar / contraer cada objeto JSON fácilmente de esta manera: ingrese la descripción de la imagen aquí


1

print_r bonita impresión para PHP

PHP de ejemplo

function print_nice($elem,$max_level=10,$print_nice_stack=array()){
    if(is_array($elem) || is_object($elem)){
        if(in_array($elem,$print_nice_stack,true)){
            echo "<font color=red>RECURSION</font>";
            return;
        }
        $print_nice_stack[]=&$elem;
        if($max_level<1){
            echo "<font color=red>nivel maximo alcanzado</font>";
            return;
        }
        $max_level--;
        echo "<table border=1 cellspacing=0 cellpadding=3 width=100%>";
        if(is_array($elem)){
            echo '<tr><td colspan=2 style="background-color:#333333;"><strong><font color=white>ARRAY</font></strong></td></tr>';
        }else{
            echo '<tr><td colspan=2 style="background-color:#333333;"><strong>';
            echo '<font color=white>OBJECT Type: '.get_class($elem).'</font></strong></td></tr>';
        }
        $color=0;
        foreach($elem as $k => $v){
            if($max_level%2){
                $rgb=($color++%2)?"#888888":"#BBBBBB";
            }else{
                $rgb=($color++%2)?"#8888BB":"#BBBBFF";
            }
            echo '<tr><td valign="top" style="width:40px;background-color:'.$rgb.';">';
            echo '<strong>'.$k."</strong></td><td>";
            print_nice($v,$max_level,$print_nice_stack);
            echo "</td></tr>";
        }
        echo "</table>";
        return;
    }
    if($elem === null){
        echo "<font color=green>NULL</font>";
    }elseif($elem === 0){
        echo "0";
    }elseif($elem === true){
        echo "<font color=green>TRUE</font>";
    }elseif($elem === false){
        echo "<font color=green>FALSE</font>";
    }elseif($elem === ""){
        echo "<font color=green>EMPTY STRING</font>";
    }else{
        echo str_replace("\n","<strong><font color=red>*</font></strong><br>\n",$elem);
    }
}

1

1: json_encode($rows,JSON_PRETTY_PRINT);devuelve datos prettificados con caracteres de nueva línea. Esto es útil para la entrada de línea de comandos, pero como has descubierto, no se ve tan bonito dentro del navegador. El navegador aceptará las nuevas líneas como la fuente (y, por lo tanto, ver la fuente de la página mostrará el bonito JSON), pero no se utilizan para formatear la salida en los navegadores. Los navegadores requieren HTML.

2 - usa este github de fuction

<?php
    /**
     * Formats a JSON string for pretty printing
     *
     * @param string $json The JSON to make pretty
     * @param bool $html Insert nonbreaking spaces and <br />s for tabs and linebreaks
     * @return string The prettified output
     * @author Jay Roberts
     */
    function _format_json($json, $html = false) {
        $tabcount = 0;
        $result = '';
        $inquote = false;
        $ignorenext = false;
        if ($html) {
            $tab = "&nbsp;&nbsp;&nbsp;&nbsp;";
            $newline = "<br/>";
        } else {
            $tab = "\t";
            $newline = "\n";
        }
        for($i = 0; $i < strlen($json); $i++) {
            $char = $json[$i];
            if ($ignorenext) {
                $result .= $char;
                $ignorenext = false;
            } else {
                switch($char) {
                    case '[':
                    case '{':
                        $tabcount++;
                        $result .= $char . $newline . str_repeat($tab, $tabcount);
                        break;
                    case ']':
                    case '}':
                        $tabcount--;
                        $result = trim($result) . $newline . str_repeat($tab, $tabcount) . $char;
                        break;
                    case ',':
                        $result .= $char . $newline . str_repeat($tab, $tabcount);
                        break;
                    case '"':
                        $inquote = !$inquote;
                        $result .= $char;
                        break;
                    case '\\':
                        if ($inquote) $ignorenext = true;
                        $result .= $char;
                        break;
                    default:
                        $result .= $char;
                }
            }
        }
        return $result;
    }

0

Lo siguiente es lo que funcionó para mí:

Contenido de test.php:

<html>
<body>
Testing JSON array output
  <pre>
  <?php
  $data = array('a'=>'apple', 'b'=>'banana', 'c'=>'catnip');
  // encode in json format 
  $data = json_encode($data);

  // json as single line
  echo "</br>Json as single line </br>";
  echo $data;
  // json as an array, formatted nicely
  echo "</br>Json as multiline array </br>";
  print_r(json_decode($data, true));
  ?>
  </pre>
</body>
</html>

salida:

Testing JSON array output


Json as single line 
{"a":"apple","b":"banana","c":"catnip"}
Json as multiline array 
Array
(
    [a] => apple
    [b] => banana
    [c] => catnip
)

También tenga en cuenta el uso de la etiqueta "pre" en html.

Espero que ayude a alguien


2
Esto no responde la pregunta. Estás volcando vars, no imprimiendo JSON formateado.
Madbreaks

0

¡La mejor manera de formatear datos JSON es así!

header('Content-type: application/json; charset=UTF-8');
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

Reemplace $ response con sus datos, que se deben convertir a JSON


0

Para aquellos que ejecutan PHP versión 5.3 o anterior, puede probar a continuación:

$pretty_json = "<pre>".print_r(json_decode($json), true)."</pre>";

echo $pretty_json;

-4

Si estás trabajando con MVC

intenta hacer esto en tu controlador

public function getLatestUsers() {
    header('Content-Type: application/json');
    echo $this->model->getLatestUsers(); // this returns json_encode($somedata, JSON_PRETTY_PRINT)
}

entonces si llamas / getLatestUsers obtendrás una salida JSON bonita;)


ver mi comentario después de que el eco donde está siendo bastante printend
webmaster

1
MVC es un tipo de diseño de marco, nada que ver con la salida de JSON.
Maciej Paprocki

es una respuesta de 2013 personas;)
webmaster
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.