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
Chapitre
json_encode
Auteurs
Achour MEHDI
Auteurs
Betz FRIEDHELM
Auteurs
Dovgal ANTONY
Auteurs
Lopes NUNO
Auteurs
Magnusson HANNES
Auteurs
Richter GEORG
Auteurs
Seguy DAMIEN
Auteurs
Vrana JAKUB
Editeur
PHP.net
Date
Titre
Programmer's Reference Guide
chapter
Zend_Json > basic usage
Auteurs
  • ZEND TECHNOLOGIES
Éditeur
framework.zend.com
Date