Php 5 - Caching de données
admin janvier 8th, 2009
Voici un système de cache d’une grande simplicité qui permet :
- De mettre en cache uniquement certaines parties de pages délivrées à l’internaute
- De mettre en cache n’importe quelle donnée sous forme de tableau (Ce qui est très intéressant pour soulager un serveur SQL par exemple)
Pour mettre en cache la sortie d’un script par exemple ou d’une partie de la sortie de ce script :
<?php // Group , Id, TTL en secondes if (!OutputCache::Start("myGroup", "myID", 600)) { // Generate some output (as you do)... OutputCache::End(); } ?>
Si votre sortie affiche des informations “aléatoires” ou différentes à chaque affichage de la page, il suffit de passer un nombre aléatoire dans le nom du groupe et de l’id du fichier de cache. Idem en cas de site multilingue, ou pour gérer la cache selon les rubriques d’un site.
Ex :
// Mise en cache de 5 possibilites d'affichage $alea_cache=rand (1,5); $cache_ttl=600; if (!OutputCache::Start("Groupe_Prod_".$code_langue."_".$id_rubrique."_".$alea_cache, "Produit_BF_".$code_langue."_".$id_rubrique."_".$alea_cache,$cache_ttl)) { // Ici on passe le code php qui va afficher les données echo "Fichier de cache ".Produit_BF_".$code_langue."_".$id_rubrique."_".$alea_cache; OutputCache::End(); }
Pour mettre en cache un tableau de donnée (array), ou le résultat d’une requête Sql.
<?php if (!$data = DataCache::Get("myGroup", "myOtherID")) { $mesdonnees=array("A","B","C"); // Group - Id - TTl en secondes DataCache::Put("myGroup", "myOtherID", 600, $mesdonnees); } print_r($mesdonnees); ?>
Voici le code de la classe :
<?php /** * o------------------------------------------------------------------------------o * | This package is licensed under the Phpguru license 2008. A quick summary is | * | that the code is free to use for non-commercial purposes. For commercial | * | purposes of any kind there is a small license fee to pay. You can read more | * | at: | * | http://www.phpguru.org/static/license.html | * o------------------------------------------------------------------------------o * * © Copyright 2008 Richard Heyes */ /** * Caching Libraries for PHP5 * * Handles data and output caching. Defaults to /dev/shm * (shared memory). All methods are static. * * Eg: (output caching) * * if (!OutputCache::Start('group', 'unique id', 600)) { * * // ... Output * * OutputCache::End(); * } * * Eg: (data caching) * * if (!$data = DataCache::Get('group', 'unique id')) { * * $data = time(); * * DataCache::Put('group', 'unique id', 10, $data); * } * * echo $data; */ class Cache { /** * Whether caching is enabled * @var bool */ public static $enabled = true; /** * Place to store the cache files * @var string */ protected static $store = '/dev/shm/'; /** * Prefix to use on cache files * @var string */ protected static $prefix = 'cache_'; /** * Stores data * * @param string $group Group to store data under * @param string $id Unique ID of this data * @param int $ttl How long to cache for (in seconds) */ protected static function write($group, $id, $ttl, $data) { $filename = self::getFilename($group, $id); if ($fp = fopen($filename, 'xb')) { if (flock($fp, LOCK_EX)) { fwrite($fp, $data); } fclose($fp); // Set filemtime touch($filename, time() + $ttl); } } /** * Reads data * * @param string $group Group to store data under * @param string $id Unique ID of this data */ protected static function read($group, $id) { $filename = self::getFilename($group, $id); return file_get_contents($filename); } /** * Determines if an entry is cached * * @param string $group Group to store data under * @param string $id Unique ID of this data */ protected static function isCached($group, $id) { $filename = self::getFilename($group, $id); if (self::$enabled && file_exists($filename) && filemtime($filename) > time()) { return true; } @unlink($filename); return false; } /** * Builds a filename/path from group, id and * store. * * @param string $group Group to store data under * @param string $id Unique ID of this data */ protected static function getFilename($group, $id) { $id = md5($id); return self::$store . self::$prefix . "{$group}_{$id}"; } /** * Sets the filename prefix to use * * @param string $prefix Filename Prefix to use */ public static function setPrefix($prefix) { self::$prefix = $prefix; } /** * Sets the store for cache files. Defaults to * /dev/shm. Must have trailing slash. * * @param string $store The dir to store the cache data in */ public static function setStore($store) { self::$store = $store; } } /** * Output Cache extension of base caching class */ class OutputCache extends Cache { /** * Group of currently being recorded data * @var string */ private static $group; /** * ID of currently being recorded data * @var string */ private static $id; /** * Ttl of currently being recorded data * @var int */ private static $ttl; /** * Starts caching off. Returns true if cached, and dumps * the output. False if not cached and start output buffering. * * @param string $group Group to store data under * @param string $id Unique ID of this data * @param int $ttl How long to cache for (in seconds) * @return bool True if cached, false if not */ public static function Start($group, $id, $ttl) { if (self::isCached($group, $id)) { echo self::read($group, $id); return true; } else { ob_start(); self::$group = $group; self::$id = $id; self::$ttl = $ttl; return false; } } /** * Ends caching. Writes data to disk. */ public static function End() { $data = ob_get_contents(); ob_end_flush(); self::write(self::$group, self::$id, self::$ttl, $data); } } /** * Data cache extension of base caching class */ class DataCache extends Cache { /** * Retrieves data from the cache * * @param string $group Group this data belongs to * @param string $id Unique ID of the data * @return mixed Either the resulting data, or null */ public static function Get($group, $id) { if (self::isCached($group, $id)) { return unserialize(self::read($group, $id)); } return null; } /** * Stores data in the cache * * @param string $group Group this data belongs to * @param string $id Unique ID of the data * @param int $ttl How long to cache for (in seconds) * @param mixed $data The data to store */ public static function Put($group, $id, $ttl, $data) { self::write($group, $id, $ttl, serialize($data)); } } ?>
Il est évident que dès qu’un site commence à monter en charge, ce genre d’outil est très efficace et simple à implémenter. Je l’utilise sur de nombreux site à forte fréquentation et ce dernier ne m’a jamais posé de problème. Il n’a pour le moment et ce depuis 2005 que des avantages. A vos éditeurs de code pour les intéressés.
Référence :
http://www.phpguru.org/static/Caching.html
- Du Php
- Comments(2)
Bonjour
Est il possible d’utiliser un système de cache comme celuique vous décrivez pour accélerer l’affichage des pages qui proviennent du cms Guppy ?
Merci d’avance
Furukoo
bonjour,
Je ne sais pas, je ne connais pas Guppy Cms. A priori il n’existe pas de module de cache sur ce dernier.
Bonnes recherches