function cache_get_cached_version ($id) { // HACK: Ignore memory requests if our OS doesn't // support memory functions if($id[0] == 'M' && !function_exists('shmop_open')) { $id[0] = 'F'; } // Determine where we should dispatch the call switch ($id[0]) { case 'F' : // This item was cached via file $cache = cache_disk_get_cached_version ($id); break; case 'M' : // This item was cached via shared memory $cache = cache_shm_get_cached_version ($id); break; default : // Nothing useful... raise an error and bail out user_error("Unknown cache ID token '{$id}'", E_ERROR); die(); } if ($cache && is_array($cache) && count($cache)==2) { // Now that we have the cached object, //let's make sure that it's still good if ($cache[0] >= time()) { return $cache[1]; } else { return false; } } else { return false; // The cache failed } } function cache_cache ($id, $value, $timeout){ // Prepare cache if(DEBUG_TIME) $value .= " time=".time(); // -- RAJOUT MT $cache = array (time() + $timeout, $value); // HACK: Ignore memory requests if our OS doesn't // support memory functions if ($id[0] == 'M' && !function_exists('shmop_open')) { $id[0] = 'F'; } // Determine where we should dispatch the call switch ($id[0]) { case 'F' : return cache_disk_cache ($id, $cache); case 'M' : return cache_shm_cache ($id, $cache); default : // Nothing useful... raise an error and bail out user_error("Unknown cache ID token '{$id}'", E_ERROR); die(); } } // --------------------------------- CACHE MEMOIRE function cache_shm_get_cached_version ($id) { // Crée l'identifiant de la ressource $id = crc32 ($id); // pose le sémaphore $sem = sem_get ($id, 1); if (!is_resource($sem)) { // Nous n'avons pas le sémaphore // Le cache échoue return false; } if (!sem_acquire ($sem)) { // Nous n'avons pas le sémaphore // Le cache échoue sem_remove ($sem); return false; } // lecture du segment de mémoire $shm = shmop_open ($id, 'a', 0, 0); if (!$shm) { // impossible de lire le segment shm sem_release ($sem); sem_remove ($sem); return false; } $value = @unserialize (shmop_read ($shm, 0, shmop_size ($shm))); // Libération du segment de mémoire shmop_close ($shm); // effacement du sémaphore sem_release ($sem); sem_remove ($sem); return $value; } function cache_shm_cache ($id, $value) { // creation de l'identifiant $id = crc32 ($id); // Linearisation de la valeur $value = serialize ($value); $value_length = strlen ($value); //Pose du sémaphore de la ressource $sem = sem_get ($id, 1); if (!is_resource($sem)) { // erreur de sémaphore : on annule tout return false; } // Acquisition du sémaphore if (!sem_acquire ($sem)) { // impossible d'obtenir le sémaphore sem_remove ($sem); return false; } $shm = shmop_open($id, "c", 0664, $value_length); if (!$shm) { // Echec de l'ouverture sem_release ($sem); sem_remove ($sem); return false; } // Ecriture des données en mémoire shmop_write ($shm, $value, 0); // Libération du segment de mémoire shmop_close ($shm); // Libération du sémaphore et fin sem_release ($sem); sem_remove ($sem); return false; } // ------------------------------- CACHE DISK function cache_disk_lock ($id) { // Détermine le dossier verrou $dir = "$id.lock"; // Essaie de créer le dossier while (!@mkdir ($dir)); // Fin. Le verrou est posé } function cache_disk_unlock ($id) { // Détermine le nom du verrou $dir = "$id.lock"; // Essaie de supprimer le verrou @rmdir ($dir); // Fin. Le verrou est libre } function cache_disk_get_cached_version ($id) { // Determine le nom du fichier $id = CACHE_DIR."CACHEXXX" . md5($id) . ".cache"; // Verrouille l'accès au fichier cache_disk_lock($id); // Accède au fichier $f = @fopen ($id, "r"); if (!$f) { cache_disk_unlock($id); return false; } // Lit la valeur $result = unserialize (file_get_contents ($id)); // Deverrouille le fichier cache_disk_unlock($id); // Retourne la valeur return $result; } function cache_disk_cache ($id, $value) { // Determine le nom du fichier $id = CACHE_DIR."CACHEXXX" . md5($id) . ".cache"; // Verrouille l'accès au fichier cache_disk_lock($id); // Accède au fichier $f = @fopen ($id, "w"); if (!$f) { cache_disk_unlock(); return false; //return array("pas de fichier possible","pas de fichier possible"); } // Ecrit la valeur $value = serialize ($value); if (fwrite($f, $value) === FALSE) { return false; //return array("pas de serialize possible","pas de serialize possible"); } // Ferme le fichier fclose($f); // Deverrouille le fichier cache_disk_unlock($id); // Fin return true; } // --------------------------------------- INSTANCIATION CACHE if (defined ("CACHE_THIS_PAGE")) { function cache_ob_uniqueid() { switch (CACHE_TYPE) { case "FILE" : $id = "F" . $_SERVER['REQUEST_URI']; break; case "SHM" : $id = "M" . $_SERVER['REQUEST_URI']; break; default : // Affiche une erreur user_error ("Type de cache invalide " . CACHE_TYPE, E_ERROR); die(); } return $id; } function cache_ob_handler ($buffer) { // Determine l'identifiant de la page $id = cache_ob_uniqueid(); // met en cache cette valeur cache_cache ($id, $buffer, CACHE_TIMEOUT); return $buffer; } // Utilisez un delai d'expiration d'une heure par exemple, // tout dépant en fait de la mise à jour du site si elle est très // fréquentes utilisez plutôt 5 à 10 min (c'est en secondes :5*60=300 pour 5 minutes) if (!defined ("CACHE_TIMEOUT")) { define (CACHE_TIMEOUT, 24*60*60);// -- ICI 1 JOUR } // Determine le type de cache if (!defined ("CACHE_TYPE")) { // Utilise les fichiers par défaut : FILE // il faut mettre : SHM pour utiliser le cache mémoire, // si la fonction shmop_open existe sur votre système sinon, // la fonction utilisera le cache fichier, pour utiliser // les fonctions shmop, compilez PHP avec l'option --enable-shmop define ("CACHE_TYPE", "FILE"); } // Determine le dossier de stockage des fichiers de cache, si vous êtes // sur un hébergement mutualisé il faudra faire attention aux LINKS et mettre // ici le chemin réel du dossier if (!defined ("CACHE_DIR")) { // Il faut mettre sur ce dossier les droits nécessaires pour PHP, // attention ne pas oublier le / (ou le \ pour Windows) à la fin define ("CACHE_DIR", "/votre/chemin/vers/dossier/cache/"); } // En mettant à TRUE cela rajoute un TIMESTAMP à la fin du fichier mis en cache, // cela vous permet de vérifier si vous visualisez la version en cache ou non // sous la forme : time=1164358210 qui rajouté à la fin du fichier if (!defined ("DEBUG_TIME")) { // Mettre à FALSE pour la production define ("DEBUG_TIME", false); } // Determine l'identifiant de la page $id = cache_ob_uniqueid(); // Vérifie si la version en cache existe if (($data = cache_get_cached_version($id))!== false){ // Ok, nous l'avons et elle est bonne // affichage et fin echo ($data); die(); } else { // Le cache est invalide. Génération ob_start ("cache_ob_handler"); } // Netoyage unset ($id); unset ($data); } // Il faut inclure ce fichier avant tout autre traitement en // oubliant pas de définir auparavant la constante CACHE_THIS_PAGE // ex : define("CACHE_THIS_PAGE",true); , // cependant il ne faut pas que vous aiyez de header ex : /* header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); */ // ce code va perturber le système de buffeurisation. // Il est à noter aussi que sur certain hébergement la buffeurisation // var être perturbé par le mode gzip positioné à On. // Dans ce cas 2 solutions le mettre à Off dans PHP.ini ou // l'écire dans un fichier .htaccess comme suit : /* <IfModule mod_gzip.c> mod_gzip_on no </IfModule> */