Pretty-printing JSON with custom indent
Recently I was in need of pretty-printing JSON in PHP with custom indentation.
While PHP 5.4 has added the constants JSON_PRETTY_PRINT
, JSON_UNESCAPED_SLASHES
, and JSON_UNESCAPED_UNICODE
which could be combined and passed in into json_encode()
to configure encoding options, there’s unfortunately no built-in way to print JSON with an indent other than 4 spaces.
For example:
$data = [
'name' => 'Andreas Möller',
'emoji' => '🤓',
'urls' => [
'https://localheinz.com',
'https://github.com/localheinz',
'https://twitter.com/localheinz',
],
];
$json = json_encode(
$data,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
will result in
{
"name":"Andreas Möller",
"emoji":"🤓",
"urls":[
"https://localheinz.com",
"https://github.com/localheinz",
"https://twitter.com/localheinz"
]
}
But what if - for some reason - I need to indent with 2 spaces, or with tabs? Or with 13 spaces?
I first turned to zendframework/zend-json
. Unfortunately it doesn’t cover all of the cases I need it to cover, so I started to search. First thing I found was a blog post from 2008, by Dave Perrett. Unfortunately, I felt uncomfortable using it (I would have preferred to find a PHP package, with tests). So I continued to search. Next stop, Stack Overflow: I found a question from 2011. Of course, one answer recommended the blog post by Dave Perrett again. A dead end, it seemed. So I continued to search. Then I took a look at the source code of composer/composer
and found Composer\Json\JsonFormatter
. Guess what? Of course it is based on the blog post by Dave Perrett.
Well, then, off I go and take the code, grab some tests, add more tests, cut away the parts that I don’t need (back-porting JSON_UNESCAPED_SLASHES
and JSON_UNESCAPED_UNICODE
for PHP versions prior to 5,4), adjust it so it can process already pretty-printed JSON, allow to pass in an indent string, and publish it as localheinz/json-printer
.
Now you can print JSON with 2 spaces, or tabs, or 13 spaces indentation, if you please:
use Localheinz\Json\Printer\Printer;
$indent = ' ';
$printer = new Printer();
$printer->print(
$json,
$indent
);
which will then result in
{
"name":"Andreas Möller",
"emoji":"🤓",
"urls":[
"https://localheinz.com",
"https://github.com/localheinz",
"https://twitter.com/localheinz"
]
}
Hope it helps!