Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structured JSON layout

Tags:

json

php

I'm working with JSON by PHP at the moment, when I encode it, it would output as:

{"username":"ND","email":"[email protected]","regdate":"8th June 2010","other":{"alternative":"ND"},"level":"6"}

When I would like it to output like this:

{
    "username": "ND",
    "email": "[email protected]",
    "regdate": "8th June 2010",
    "other":
    {
        "alternative": "ND"
    },
    "level":"6"
}

So that me and my other developers can read it well enough when structured. How can I do this?

Example also like this:

https://graph.facebook.com/19292868552

Cheers

like image 704
MacMac Avatar asked Aug 14 '10 21:08

MacMac


1 Answers

I could find this useful myself, so here's a little function I wrote:

<?php
function json_pretty_encode($obj)
{
 $json = json_encode($obj);
 if (!$json) return $json;

 $f = '';
 $len = strlen($json);

 $depth = 0;
 $newline = false;

 for ($i = 0; $i < $len; ++$i)
 {
  if ($newline)
  {
   $f .= "\n";
   $f .= str_repeat(' ', $depth);
   $newline = false;
  }

  $c = $json[$i];
  if ($c == '{' || $c == '[')
  {
   $f .= $c;
   $depth++;
   $newline = true;
  }
  else if ($c == '}' || $c == ']')
  {
   $depth--;
   $f .= "\n";
   $f .= str_repeat(' ', $depth);
   $f .= $c;
  }
  else if ($c == '"')
  {
   $s = $i;
   do {
    $c = $json[++$i];
    if ($c == '\\')
    {
     $i += 2;
     $c = $json[$i];
    }
   } while ($c != '"');
   $f .= substr($json, $s, $i-$s+1);
  }
  else if ($c == ':')
  {
   $f .= ': ';
  }  
  else if ($c == ',')
  {
   $f .= ',';
   $newline = true;
  }
  else
  {
   $f .= $c;
  }
 }

 return $f;
}
?>

It's naive, trusting that PHP will return a valid JSON string. It could be written more concisely, but it's easy to modify this way. (And of course this adds unnecessary overhead in production scenarios where only a machine reads the text.)

Edit: Added an else clause to catch numbers and other unknown chars.

like image 193
Matthew Avatar answered Sep 28 '22 22:09

Matthew