I\'m building a PHP script that feeds JSON data to another script. My script builds data into a large associative array, and then outputs the data using json_encode
If you are on firefox install JSONovich. Not really a PHP solution I know, but it does the trick for development purposes/debugging.
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" }
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(['<', '>', '&'], ['<', '>', '&'], $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);
}
}
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);
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);
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
}
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);
}
}