[tutoriel] Mise en cache en PHP, la version complète.

Discussion dans 'Administration d'un site Web' créé par lyonist, 29 Mai 2009.

  1. lyonist
    lyonist WRInaute discret
    Inscrit:
    5 Août 2008
    Messages:
    152
    J'aime reçus:
    0
    Bonjour,

    fandecine a fait un superbe script de mise en cache en PHP il est accesible sur cette page :
    https://www.webrankinfo.com/forum/t/script-mise-en-cache-des-pages-php.28614/

    Son script fonctionne très bien mais que pour les petits/moyens sites, s'il y a plusque 1 million fichiers cache ça va provoquer les performance du serveur.

    j'ai ajouté des petits trucs pour l'améliorer pour qu'il supporte 600 millions fichiers cache facilement.

    voici le script final :

    Code:
    <?php
    $urldemandee=$_SERVER['REQUEST_URI']; //on lit l'adresse de la page
    $urldemandee=ereg_replace('/','-',$urldemandee); // on tranforme l'adresse en nom de fichier
    
    if($urldemandee=="-") $urldemandee="-index.html"; // si l'adresse est la racine du site, on ajoute index.html
    if(!is_dir("cache/".substr(md5($_SERVER['REQUEST_URI']), -3))) { mkdir("cache/".substr(md5($_SERVER['REQUEST_URI']), -3)); } 
    	$fichierCache="cache/".substr(md5($urldemandee), -3)."/".$urldemandee.".html"; // on construit le chemin du fichier cache de la page
    	
    if (@filemtime($fichierCache)<time()-(3600*24*360)) { //si la page n'existe pas dans le cache ou si elle a expir&eacute;
    	ob_start(); // on d&eacute;marre la bufferisation de la page: rien de ce qui suit n'est envoy&eacute; au navigateur
    	echo "Votre contenu à mettre en cache ici";
    	$contenuCache = ob_get_contents(); // on recuperre le contenu du buffer
    	ob_end_flush();// on termine la bufferisation
    	$fd = fopen("$fichierCache", "w"); // on ouvre le fichier cache
    	 if ($fd) {
    		    fwrite($fd,$contenuCache); // on ecrit le contenu du buffer dans le fichier cache
    		    fclose($fd);
    	    }
    } 
    
    else { // le fichier cache existe d&eacute;j&agrave; 
     include ($fichierCache); // on le copie ici
    }
    ?>	
    Le principe est simple, c'est de convertir chaque "page actuelle" en MD5, et de créer un dossier des 3 première caractères, et après on compare, si le 3 premières caractères du MD5 de notre page correspond à un dossier on met dedans.. donc on aura en total 15 x 15 x 15 (15 puissance 3 correspond à l'hexa (15) X 3 caractères) dossiers cache, ce qui fait 3375 dossiers.

    donc pour 2 millions pages on aura seulement 592 fichiers par dossier :D

    Voilà, je l'ai fais par besoin, mon serveur rame à cause de quelque millions fichiers cache, je me suis dis ça peut être utile pour quelques membres sur WRI.
     
  2. nickargall
    nickargall WRInaute accro
    Inscrit:
    13 Juin 2005
    Messages:
    6 601
    J'aime reçus:
    4
    C'est vraiment pas bête :)
     
  3. VisitezMonSite
    VisitezMonSite WRInaute impliqué
    Inscrit:
    7 Mai 2009
    Messages:
    735
    J'aime reçus:
    0
    C'est vraiment sympa de partager tes modifs!
     
  4. fabor
    fabor WRInaute discret
    Inscrit:
    17 Mars 2005
    Messages:
    122
    J'aime reçus:
    0
    la différence de temps est très significative?
     
  5. lyonist
    lyonist WRInaute discret
    Inscrit:
    5 Août 2008
    Messages:
    152
    J'aime reçus:
    0
    temps de réponse ? ben oui, ce n'est pas comme on cherche dans 6 millions fichiers comme 5000 fichiers ou moins.
     
  6. petit-ourson
    petit-ourson WRInaute impliqué
    Inscrit:
    31 Mai 2004
    Messages:
    680
    J'aime reçus:
    0
    Une chaine a toujours le même md5, mais es-tu sûr que la valeur d'un md5 représente toujours la même chaine ?
     
  7. VisitezMonSite
    VisitezMonSite WRInaute impliqué
    Inscrit:
    7 Mai 2009
    Messages:
    735
    J'aime reçus:
    0
    Petit-ourson je ne vois pas la pertinence de ta question par rapport au sujet, puisqu'un md5 est toujours le même pour une chaine donnée, et que lyonist se sert des 3 premiers charactères du md5 du nom de la page demandé pour créer/classer dans un dossier, mais que le nom du fichier cache reste "en clair" il n'y a pas de problème. Tu n'as pas dû bien lire le premier post ou alors j'ai loupé quelque chose?

    Code:
    $fichierCache="cache/".substr(md5($urldemandee), -3)."/".$urldemandee.".html"; // on construit le chemin du fichier cache de la page
     
  8. petit-ourson
    petit-ourson WRInaute impliqué
    Inscrit:
    31 Mai 2004
    Messages:
    680
    J'aime reçus:
    0
    Effectivement j'avais lu un peu trop rapidement le premier message.
     
  9. WebRankInfo
    WebRankInfo Admin
    Membre du personnel
    Inscrit:
    19 Avril 2002
    Messages:
    20 720
    J'aime reçus:
    779
    Merci pour ce partage d'infos et de code. Pour ma part le nom du fichier de cache est quasi toujours associé à un ID (nombre), par exemple pour un topic du forum ce sera l'ID du topic. Donc c'est simple de répartir les fichiers dans des sous-répertoires basés sur les chiffres.
    J'ai testé jusqu'à 100.000 fichiers par répertoire sans voir de baisse sensible des perfs (serveur apache, je ne me prononce pas pour IIS ;-))
     
  10. fandecine
    fandecine WRInaute passionné
    Inscrit:
    2 Avril 2005
    Messages:
    1 873
    J'aime reçus:
    0
    Aurais-je un fils ... spiryuel !? :mrgreen:

    Merci lyonist pour ces modifs trés pertinantes :wink:

    Olivier, si le nombre de fichiers dans un répertoire doit poser des problèmes c'est au niveau du SE (Linux par exemple) pas au niveau d'apache :D

    Je ne suis pas allé jusqu'à 100.000 fichiers dans un répertoire, mais le nombre n'influe pas sur le temps d'accés en adressage direct à un fichier (sauf avec une recherche). Par contre cela peut poser des problémes au niveau de l'optimisation de l'occupation de l'espace disque (avec un système de fichier EXT3 généralement utilisé sous linux) surtout pour un systéme de cache qui par définition effec et recré des fichiers (le disque peut vite resembler à un morceau de gruyère). C'est plus à ce niveau que le morcellement en répertoire est intéressant.

    Maintenant, en matière de cache, je n'utilise plus ce systéme qui consomme beaucoup d'espace disque innutile et ne permet pas de modifier l'apparence des pages sans éffacer le cache. Il est bien plus efficace de sérialiser les données dynamique (de façon indépendante de l'habillage des données) et de stocker sur le disque la chaine sérialisée. Cela permet en plus de pouvoir utiliser ces données sur des pages différentes et diminue énormément la redondance.

    Je crois me rappeller que j'avais promis de publier une classe PHP qui fait ce boulot, mais par manque de temps libre :mrgreen:

    Je vais m'y remettre :wink:
     
  11. phpmikedu83
    phpmikedu83 WRInaute passionné
    Inscrit:
    6 Août 2005
    Messages:
    1 012
    J'aime reçus:
    0
    En utilisant des preg_replace déjà, ça sera plus performant... ;)
     
  12. bruno212
    bruno212 WRInaute occasionnel
    Inscrit:
    13 Février 2005
    Messages:
    449
    J'aime reçus:
    0
    Bonsoir,

    On peut aussi utiliser la librairie CacheLite, disponible sur Pear
    http://pear.php.net/package/Cache_Lite

    Cette librairie permet de mettre en cache le résultat d'une fonction php, par exemple, une fonction qui génère un menu. Ainsi celui-ci ne sera calculé qu'une seule fois.
    De plus, on peut définir la durée de validité du cache.
    Les fichiers plus vieux que le temps de cache spécifié ne sont plus utilisés et un autre fichier est calculé.

    à plus
     
  13. VisitezMonSite
    VisitezMonSite WRInaute impliqué
    Inscrit:
    7 Mai 2009
    Messages:
    735
    J'aime reçus:
    0
    @fandecine: as-tu eu le temps de faire ta classe PHP pour la fonction cache (avec la modif des sous dossiers donnée par lyonist ca serait encore mieux) ?

    Ou un str_replace c'est encore plus rapide :)
     
  14. FortTrafic
    FortTrafic WRInaute passionné
    Inscrit:
    11 Décembre 2012
    Messages:
    1 202
    J'aime reçus:
    18
    Bonjour,
    Est-ce que ce script de mise en cache a subit une autre évolution depuis 2009 sur une autre discussion sur WRI ?

    Est-ce qu'il est possible de rajouter un peu de code pour que lorsque un fichier cache doit être créé dans un sous répertoire, il y ait une vérification des fichiers trop vieux dans ce sous répertoire afin de les supprimer?

    Cela permettrait de faire le ménage automatiquement petit à petit.

    J'ai trouvé cette fonction mais pas sûr de comment l'intégrer dans le script de lyonist :

    Code:
    function destroy($dir) {
    $mydir = opendir($dir);
    while($file = readdir($mydir)) {
        if($file != "." && $file != "..") {
            chmod($dir.$file, 0777);
            if(is_dir($dir.$file)) {
                chdir('.');
                while($dir.$file) {
                    if(date("U",filectime($file) >= time() - 3600)
                    {
                        unlink($dir.$file)
                    }
                }
    
            }
            else
                unlink($dir.$file) or DIE("couldn't delete $dir$file<br />");
        }
    }
    closedir($mydir);
    }
    Bien sûr il faudrait changer 3600 par 3600*24*360 ou mieux l'ajouter en argument de la fonction.
     
Chargement...
Similar Threads - [tutoriel] cache PHP Forum Date
[tutoriel] Tracking du web social (clics sur boutons Facebook, Twitter...) Google Analytics 2 Juillet 2011
[tutoriel] Le guide du tracking avec Google Analytics Google Analytics 25 Octobre 2010
[Tutoriel] Etudier la longue traine pour améliorer le référencement Techniques avancées de référencement 24 Juin 2010
Outil pour déterminer délai mise en cache navigateur Développement d'un site Web ou d'une appli mobile 8 Juin 2022
problème avec la mise en cache des images de mon site Développement d'un site Web ou d'une appli mobile 19 Décembre 2021
Apparence d'une page en cache et positionnement Crawl et indexation Google, sitemaps 24 Novembre 2021
Site à cacher dans l'historique de navigation Administration d'un site Web 5 Octobre 2021
Javascript API cache query non url ? Développement d'un site Web ou d'une appli mobile 18 Août 2021
Cache Etag nginx et PHP ? Administration d'un site Web 7 Août 2021
Fetch quelles techniques de cache ? Développement d'un site Web ou d'une appli mobile 1 Août 2021
Supprimer la version en cache de dizaines de PDF Crawl et indexation Google, sitemaps 11 Janvier 2021
Le contenu « caché » par un accordéon a-t-il autant de poids SEO que du texte « normal » ? Référencement Google 6 Janvier 2021
Cache avec contenu variable ? Développement d'un site Web ou d'une appli mobile 2 Décembre 2020
Light House et cache Varnish chez Gandi Référencement Google 30 Octobre 2020
Quel impact sur le SEO en cas de blocage du cache Google ? Référencement Google 23 Août 2020
Quelle config cache pour mariaDB ? Administration d'un site Web 15 Août 2020
Memcached/PHP gestion de sessions Développement d'un site Web ou d'une appli mobile 22 Juillet 2020
WordPress Lignes restantes après changement de plugin de cache URL Rewriting et .htaccess 5 Juin 2020
Nettoyer son cache navigateur Administration d'un site Web 15 Février 2020
Referral : googleweblight.com avec Cache-control : no-transform ? Google Analytics 31 Décembre 2019