Snippet #20 ~ PHP: Stocker facilement des données JSON compressées dans un fichier

Deux petites fonctions très simple pour stocker/déstocker des informations multiples dans un fichier texte

Avantages

  1. Permet de créer des scripts sans utiliser de base de données (ex: shaarli,codiad,blogotext v1.x,twidoo utilisent cette technique)
  2. Stocke les données au format JSON, un format léger et structuré de plus en plus utilisé par toutes sorte de langages/programmes
  3. Compresse au maximum les données avec les fonctions gzdeflate et gzinflate afin de réduire la taille des fichiers et des transferts de données

Code

<?php
         function store($file,$datas){file_put_contents($file,gzdeflate(json_encode($datas)));}
         function unstore($file){return json_decode(gzinflate(file_get_contents($file)),true);}
?>

 

Exemple d’utilisation

    <?php
            $users[0]['name'] = 'idleman';
            $users[0]['age'] = 25;

            $users[1]['name'] = 'other man';
            $users[1]['age'] = 51;

            store('utilisateurs.json.gz',$users);
            $my_users = unstore('utilisateurs.json.gz');

            echo 'Mon utilisateur 1 s\'appelle '.$my_users[0]->name.' et a '.$my_users[0]->age.' ans<br/>';
            echo 'Mon utilisateur 2 s\'appelle '.$my_users[1]->name.' et a '.$my_users[1]->age.' ans<br/>';
    ?>

 

13 réactions au sujet de « Snippet #20 ~ PHP: Stocker facilement des données JSON compressées dans un fichier »

  1. Fylhan Réponse

    Merci pour ce snippet. As-tu fait un petit test pour savoir quand est-ce que le coût de la compression devenait plus intéressant que le coût du transfert de données, en fonction de la taille des données ? Avec toutes les approximations dûes au fait que la bande passante n’est jamais la même partout tout le temps.
    Bref, c’est ce qui m’a toujours empêché d’utiliser ce genre de technique jusqu’à présent, donc je ferai bien le test un jour, mais si jamais tu as déjà des idées…

    • Idleman Auteur ArticleRéponse

      Non je ne l’ai pas fait, mais c’est une très bonne remarque ça fvaudrait le coup de s’y pencher, je pense que le cout de compression/décompression est moindre mais c’est à vérifier 🙂

    • sebsauvage Réponse

      Je n’ai plus le lien, mais de mémoire les CPU sont capables de décompresser du zlib à un débit supérieur aux débits de interfaces des disques durs. zlib est vraiment très rapide.

      Je n’ai aucun problème pour lire le fichier ainsi de mon Shaarli (http://sebsauvage.net/links/) (2,4 Mo compressé): Vous pouvez passer aux pages 2/3/4.. sans ralentissement, malgré le fait que j’ai 20 000 visiteurs par jour et que je sois sur un mutualisé.

      Quant aux transferts réseau, il peut être utile (selon les cas), d’activer mod_gzip: Le gain sur les fichiers html, css et javascripts sont appréciables. (Et justement, ça utilise du zlib)
      Mais il ne faut pas oublier que plus que la compression, un bon paramétrage du cache côté client fera gagner énormément de temps au chargement des pages (typiquement les images, css et javascript qui ne changent pas souvent).

  2. Bronco Réponse

    Excellent, ça, je prends illico ! Merci Idle ^^
    (le stockage des données reste souvent un peu prise de tête, voilà qui simplifie bien la tâche…)

  3. sebsauvage Réponse

    Juste une petite précision: Nécessite php >= 5.2 (à cause de json_encode()), donc pas chez Free.fr.

    Mais c’est effectivement très efficace (il faudra, un jour, que je boucle mon article sur le stockage sous forme de fichiers).

    Il y a quelques gotchas:
    – cette solution ne gère pas les accès concurrents (ça peut poser problème s’il y a beaucoup d’écriture simultanées, mais ne pose typiquement pas de problème dans des logiciels comme Shaarli, car mono-utilisateur).
    il faut limiter le nombre de fichiers par répertoire, car c’est bien ça qui ralentit les logiciels, et non le fait de lire des fichiers. C’est pour cela que dans ZeroBin (ou dans Squid-cache) les fichiers sont répartis sur plusieurs niveaux de sous-répertoires.

    Si vous commencez à dépasser le millier de fichiers dans un répertoire, vous allez commencer à avoir des problèmes de performances (car vous vous reposez sur l’index des systèmes de fichiers pour trouver un fichier particulier, et ces derniers ne sont pas très performants).

    Il y a plusieurs façons de segmenter: Par date (pour un blog par exemple):
    2012/
    2012/10
    2012/10/23/…

    Ainsi à mois d’être un fou-furieux qui poste plusieurs milliers d’articles et commentaires par jour, aucun risque de ralentissement.

    ou répartir avec un hash (comme ZeroBin/Squid):
    5a/fb/24/…. (si votre hash est 5afb24…)

    • Idleman Auteur ArticleRéponse

      Merci pour toutes ces précisions, nottaemment pour le ralentissement lié à l’indexation, j’ignorais que c’était consommateur, même pour un millier de fichier j’aurais cru que ça dépotait ^^.

      M’enfin il est clair que cette solution n’est pas adaptée a tout les scripts, c’est la raison pour laquelle j’utilise encore des SGBD pour les miens.

      De plus l’aspect relationnel manquant deviens vite bloquant pour des script type blog et autres, je le déconseille donc vivement pour ma part dans ce genre d’applications.

  4. Bronco Réponse

    +1
    Toutefois, la plupart des applis qu’on se fait en mode Itch’n’Scratch (donc mono utilisateur avec ergonomie à la scie sauteuse seewhatImean ^^) n’ont pas tellement besoin de beaucoup de ressources et on a plutôt besoin de portions de codes ‘lego’ qui fonctionnent vite, sans complications ni perte de temps.
    ^^

  5. Msieur Toph' Réponse

    Pas mal …
    Mais ça pose un souci si on veut stocker des objets. JSON_decode ne sait pas les décoder et les reconstruire (contrairement au serialize() … certes moins récent, mais plus efficace en l’occurence)

    • Idleman Auteur ArticleRéponse

      Rien n’empêche d’allier les deux cela dit ^^, mais tu marque un point concernant cette faiblesse du json_encode, peut être dans une prochaine version de php…

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.