开发者

Pretty-Printing JSON with PHP

I'm building a PHP script that feeds JSON data to another script. My script b开发者_Go百科uilds data into a large associative array, and then outputs the data using json_encode. Here is an example script:

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

The above code yields the following output:

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

This is great if you have a small amount of data, but I'd prefer something along these lines:

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

Is there a way to do this in PHP without an ugly hack? It seems like someone at Facebook figured it out.


PHP 5.4 offers the JSON_PRETTY_PRINT option for use with the json_encode() call.

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

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


This function will take JSON string and indent it very readable. It also should be convergent,

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

Input

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

Output

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

Code

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


Many users suggested that you use

echo json_encode($results, JSON_PRETTY_PRINT);

Which is absolutely right. But it's not enough, the browser needs to understand the type of data, you can specify the header just before echo-ing the data back to the user.

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

This will result in a well formatted output.

Or, if you like extensions you can use JSONView for Chrome.


I realize this question is asking about how to encode an associative array to a pretty-formatted JSON string, so this doesn't directly answer the question, but if you have a string that is already in JSON format, you can make it pretty simply by decoding and re-encoding it (requires PHP >= 5.4):

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

Example:

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;

This outputs:

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


I had the same issue.

Anyway I just used the json formatting code here:

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

Works well for what I needed it for.

And a more maintained version: https://github.com/GerHobbelt/nicejson-php


Gluing several answers together fit my need for existing json:

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
}


I have used this:

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

Or use php headers as below:

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


much easier to remind: enter 128

128 is a synonyme for the constant "JSON_PRETTY_PRINT"

( PHP Docs Site)

json_encode($json,128);
//similar to
json_encode($json,JSON_PRETTY_PRINT );


I took the code from Composer : https://github.com/composer/composer/blob/master/src/Composer/Json/JsonFile.php and nicejson : https://github.com/GerHobbelt/nicejson-php/blob/master/nicejson.php Composer code is good because it updates fluently from 5.3 to 5.4 but it only encodes object whereas nicejson takes json strings, so i merged them. The code can be used to format json string and/or encode objects, i'm currently using it in a Drupal module.

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


best way to format JSON data is like this!

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

Replace $response with your Data which is required to be converted to JSON


If you are on firefox install JSONovich. Not really a PHP solution I know, but it does the trick for development purposes/debugging.


Have color full output: Tiny Solution

Code:

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


Simple way for php>5.4: like in Facebook graph

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

Result in browser

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


If you have existing JSON ($ugly_json)

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


Use <pre> in combination with json_encode() and the JSON_PRETTY_PRINT option:

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


You can modify Kendall Hopkins' answer a little in the switch statement to get a pretty clean looking and nicely indented printout by passing a json string into the following:

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;

}

Now just run the function prettyPrint( $your_json_string ); inline in your php and enjoy the printout. If you're a minimalist and don't like brackets for some reason, you can get rid of those easily by replacing the $char.="<br>"; with $char="<br>"; in the top three switch cases on $char. Here's what you get for a google maps API call for the city of 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" }


For those running PHP version 5.3 or before, you may try below:

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

echo $pretty_json;


If you used only $json_string = json_encode($data, JSON_PRETTY_PRINT);, you will get in the browser something like this (using the Facebook link from the question :) ):

Pretty-Printing JSON with PHP

but if you used a chrome Extension like JSONView (even without the PHP option above), then you get a more pretty readable debuggable solution where you can even Fold/Collapse each single JSON object easily like this:

Pretty-Printing JSON with PHP


You could do it like below.

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

Above would output kind of like Facebook.

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


Classic case for a recursive solution. Here's mine:

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

Usage:

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\""
    }
}

Cheers


This solution makes 'really pretty' JSON. Not exactly what the OP was asking for, but it lets you visualise the JSON better.

/**
 * 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);
}

}


print_r pretty print for PHP

Example PHP

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 - json_encode($rows,JSON_PRETTY_PRINT); returns prettified data with newline characters. This is helpful for command line input, but as you've discovered doesn't look as pretty within the browser. The browser will accept the newlines as the source (and thus, viewing the page source will indeed show the pretty JSON), but they aren't used to format the output in browsers. Browsers require HTML.

2 - use this fuction github

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


here's the function i use myself, the api is just like json_encode, except it has a 3rd argument exclude_flags in case you want to exclude some of the default flags (like JSON_UNESCAPED_SLASHES)

function json_encode_pretty($data, int $extra_flags = 0, int $exclude_flags = 0): string
{
    // prettiest flags for: 7.3.9
    $flags = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | (defined("JSON_UNESCAPED_LINE_TERMINATORS") ? JSON_UNESCAPED_LINE_TERMINATORS : 0) | JSON_PRESERVE_ZERO_FRACTION | (defined("JSON_THROW_ON_ERROR") ? JSON_THROW_ON_ERROR : 0);
    $flags = ($flags | $extra_flags) & ~ $exclude_flags;
    return (json_encode($data, $flags));
}


I usually use this one of these one-liners.

If you already have an JSON string, you can simply use a combination of echo() and print_r(). Don't forget to pass the second parameter of print_r() to true so that it returns the value rather than printing it:

echo('<pre>' . print_r($json, true) . '</pre>');

or you can use die() which is handy for debugging:

die('<pre>' . print_r($json, true) . '</pre>');

If you have an array, you need to convert it to a JSON string before. Be sure to set the second parameter of json_encode() with the JSON_PRETTY_PRINT flag so your JSON will be correctly rendered:

echo('<pre>' . print_r(json_encode($array, JSON_PRETTY_PRINT), true) . '</pre>');

or for debugging:

die('<pre>' . print_r(json_encode($array, JSON_PRETTY_PRINT), true) . '</pre>');


The following is what worked for me:

Contents of 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>

output:

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
)

Also note the use of "pre" tag in html.

Hope that helps someone


If you are working with MVC

try doing this in your controller

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

then if you call /getLatestUsers you will get a pretty JSON output ;)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜