Pretty-printing JSON with custom indent

localheinz profile image Andreas Möller Originally published at localheinz.com on ・2 min read

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!

Posted on by:


markdown guide