Deux petites fonctions très simple pour stocker/déstocker des informations multiples dans un fichier texte
Avantages
- Permet de créer des scripts sans utiliser de base de données (ex: shaarli,codiad,blogotext v1.x,twidoo utilisent cette technique)
- Stocke les données au format JSON, un format léger et structuré de plus en plus utilisé par toutes sorte de langages/programmes
- 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/>'; ?>
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…
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 🙂
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).
Il est certain que shaarli est un bel exemple de gestion par fichiers 🙂
Excellent ! Et bon à savoir 🙂
Merci de ce retour.
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…)
Y’a pas de quoi le warrior :p
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…)
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.
+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.
^^
Je ne peux que plussoiyer, c’est le cas de mon twidoo.
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)
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…