JSON in bella printing con PHP

Sto costruendo uno script PHP che alimenta i dati JSON in un altro script. Il mio script crea i dati in un arrays associativo di grandi size e quindi emette i dati utilizzando json_encode . Ecco uno script di esempio:

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

Il codice sopra riportto produce il seguente risultato:

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

Questo è fantastico se hai una piccola quantità di dati, ma preferirei qualcosa in questo senso:

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

C'è un modo per farlo in PHP senza un brutto trucco? Sembra che qualcuno su Facebook l'abbia capito.

    PHP 5.4 offre l'opzione JSON_PRETTY_PRINT per l'uso con la chiamata json_encode() .

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

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

    Questa function richiede una string JSON e il rientro è molto leggibile. Dovrebbe anche essere convergente,

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

    Ingresso

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

    Produzione

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

    Codice

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

    Ho avuto lo stesso problema.

    Comunque ho appena usato il codice di formattazione JSON qui:

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

    Funziona bene per quello che mi serviva.

    E una versione più curata: https://github.com/GerHobbelt/nicejson-php

    Molti utenti hanno suggerito di utilizzare

     echo json_encode($results, JSON_PRETTY_PRINT); 

    Che è assolutamente giusto. Ma non è sufficiente, il browser deve capire il tipo di dati, è ansible specificare l'intestazione prima di riportre i dati all'utente.

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

    Ciò si tradurrà in un output ben formattato.

    Oppure, se ti piacciono le estensioni puoi utilizzare JSONView per Chrome.

    Se sei su Firefox installa JSONovich . Non proprio una soluzione PHP, lo so, ma fa il trucco per scopi di sviluppo / debugging.

    Ho preso il codice da Composer: https://github.com/composer/composer/blob/master/src/Composer/Json/JsonFile.php e nicejson: https://github.com/GerHobbelt/nicejson-php/blob /master/nicejson.php Il codice del compositore è buono perché si aggiorna fluidamente dalla 5.3 alla 5.4 ma codifica solo l'object mentre nicejson prende le stringhe json, quindi le ho unite. Il codice può essere usato per formattare json string e / o oggetti di codifica, attualmente lo sto usando in un module 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; } 

    Mi rendo conto che questa domanda sta chiedendo come codificare un arrays associativo su una string JSON abbastanza formattata, quindi questo non risponde direttamente alla domanda, ma se hai una string che è già in formato JSON, puoi renderla semplicemente decodificandolo e ricodificandolo (richiede PHP> = 5.4):

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

    Esempio:

     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; 

    Questo produce:

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

    Utilizza <pre> in combinazione con json_encode() e l'opzione JSON_PRETTY_PRINT :

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

    È ansible modificare la risposta di Kendall Hopkins un po 'nell'istruzione switch per get una printing dall'aspetto piuttosto pulito e gradevolmente rientrata passando una string json nel seguente modo:

     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; 

    }

    Ora basta eseguire la function prettyPrint ($ your_json_string); in linea nel tuo php e goditi la printing. Se sei un minimalist e non ti piacciono le parentesi per qualche motivo, puoi eliminarle facilmente sostituendo $char.="<br>"; con $char="<br>"; nei primi tre casi di switch su $ char. Ecco cosa ottieni per una chiamata all'API di Google Maps per la città di 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" } 

    Avere un output a colors: soluzione minuscola

    Codice:

     $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]; 

    Se hai usato solo $json_string = json_encode($data, JSON_PRETTY_PRINT); , si otterrà nel browser qualcosa del genere (utilizzando il collegamento di Facebook dalla domanda :)): inserisci la descrizione dell'immagine qui

    ma se hai usato un'estensione di Chrome come JSONView (anche senza l'opzione PHP sopra), allora ottieni una soluzione di debugable più leggibile where puoi anche piegare / comprimere each singolo object JSON in questo modo: inserisci la descrizione dell'immagine qui

    Potresti farlo come sotto.

     $arrays = arrays( "a" => "apple", "b" => "banana", "c" => "catnip" ); foreach ($arrays as $a_key => $a_val) { $json .= "\"{$a_key}\" : \"{$a_val}\",\n"; } header('Content-Type: application/json'); echo "{\n" .rtrim($json, ",\n") . "\n}"; 

    Sopra uscirà un po 'come Facebook.

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

    Modo semplice per php> 5.4: come nel grafico di Facebook

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

    Risultato nel browser

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

    Se hai già JSON $ ugly_json esistente:

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

    Custodia classica per una soluzione ricorsiva. Ecco il mio:

     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 = arrays_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.arrays_shift($j); } else if($c == '}' || $c == ']') { arrays_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 = arrays('foo' => 1, 'bar' => 'This "is" bar', 'baz' => arrays('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\"" } } 

    Saluti

    print_r pretty print per PHP

    Esempio PHP

     function print_nice($elem,$max_level=10,$print_nice_stack=arrays()){ if(is_arrays($elem) || is_object($elem)){ if(in_arrays($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_arrays($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 – json_encode($rows,JSON_PRETTY_PRINT); restituisce dati prettificati con caratteri di nuova row. Questo è utile per l'input da linea di command, ma come hai scoperto non sembra carino nel browser. Il browser accetterà le newline come sorgente (e quindi, visualizzare l'origine della pagina mostrerà in effetti il ​​grazioso JSON), ma non vengono utilizzate per formattare l'output nei browser. I browser richiedono HTML.

    2 – usa questo github di 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;"; $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 '{': $tabcount++; $result .= $char . $newline . str_repeat($tab, $tabcount); break; 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; } 

    Quello che segue è quello che ha funzionato per me:

    Contenuto di test.php:

     <html> <body> Testing JSON arrays output <pre> <?php $data = arrays('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 arrays, formatted nicely echo "</br>Json as multiline arrays </br>"; print_r(json_decode($data, true)); ?> </pre> </body> </html> 

    produzione:

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

    Nota anche l'uso del tag "pre" in html.

    Spero che aiuti qualcuno

    Se stai lavorando con MVC

    prova a farlo nel tuo controller

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

    quindi se chiami / getLatestUsers otterrai un bel output JSON;)

    Non ho una reputazione sufficiente per rispondere a Kendall Hopkins, ma ho trovato un bug nel suo prettifier (è venuto fuori imbarazzato pure)

    Questa row dovrebbe essere modificata:

     if( $char === '"' && $prev_char != '\\' ) { 

    a

     if( $char === '"' && ($prev_char != '\\' && $prev_prev_char != '\\' ) { 

    Il prettifier si rompe e produce un json non valido quando una string termina con una barra rovesciata in questo modo:

     "kittens\\"