Formatage json en PHP

PHP possède des méthodes pour lire (json_decode) ou encoder (json_encode) des objets json. La chaîne de caractères retournée par cette dernière méthode est malheureusement illisible car sans indentation. Et comme l'un des intérêts du json, c'est justement de pouvoir être lu facilement par un humain, voici comment corriger cela...

En fait, une option JSON_PRETTY_PRINT existe pour la méthode json_encode, mais elle n'est disponible qu'à partir de PHP 5.4. Donc, pour ceuses qui sont encore bloqués comme moi à la version 5.3.x, une fonction extraite du framework Zend à peine modifiée peut faire l'affaire :

/**
 *  Formater une chaîne json pour qu'elle soit lisible.
 *  From Zend_Json::prettyPrint
 *  @param {String} $json Chaîne au format json
 *  @return {String} Chaîne json formatée.
 */
public static function prettyJson($json) {
    $tokens = preg_split('|([\{\}\]\[,])|', $json, -1, PREG_SPLIT_DELIM_CAPTURE);
    $result = '';
    $indent = 0;
    $ind    = '    ';
    $lineBreak = "\n";
    $inLiteral = false;
    foreach($tokens as $token) {
        if ($token == '') {
            continue;
        }
        $prefix = str_repeat($ind, $indent);
        if (!$inLiteral && ($token == '{' || $token == '[')) {
            $indent++;
            if (($result != '') && ($result[(strlen($result)-1)] == $lineBreak)) {
                $result .= $prefix;
            }
            $result .= $token . $lineBreak;
        } elseif (!$inLiteral && ($token == '}' || $token == ']')) {
            $indent--;
            $prefix = str_repeat($ind, $indent);
            $result .= $lineBreak . $prefix . $token;
        } elseif (!$inLiteral && $token == ',') {
            $result .= $token . $lineBreak;
        } else {
            $result .= ( $inLiteral ? '' : $prefix ) . $token;
            // Count # of unescaped double-quotes in token, subtract # of
            // escaped double-quotes and if the result is odd then we are 
            // inside a string literal
            if ((substr_count($token, "\"")-substr_count($token, "\\\"")) % 2 != 0) {
                $inLiteral = !$inLiteral;
            }
        }
    }
    return $result;
}
Fonction de formatage d'une chaîne de caractères représentant un objet json, tirée du framework Zend.

L'opération a évidemment un coût, par le traitement supplémentaire qu'elle implique mais aussi par la taille de la chaîne résultante. Après quelques tests, il s'avère que le poids de mes fichiers json a augmenté de 45% environ. Loin d'être négligeable donc. A utiliser uniquement pour des fichiers que l'on consulte directement (surtout que des chaînes trop longues font méchamment ramer Gedit).

Titre
Manuel PHP
Auteurs
Mehdi ACHOUR
Auteurs
Friedhelm BETZ
Auteurs
Antony DOVGAL
Auteurs
Nuno LOPES
Auteurs
Hannes MAGNUSSON
Auteurs
Georg RICHTER
Auteurs
Damien SEGUY
Auteurs
Jakub VRANA
Editeur
PHP.net
Date
Chapitre
json_encode
Titre
Programmer's Reference Guide
Auteurs
  • ZEND TECHNOLOGIES
Éditeur
framework.zend.com
Date
chapter
Zend_Json > basic usage