Consultez la formation SEO spéciale Wordpress
par WebRankInfo / Ranking Metrics

Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 15:26

:P voila, j'ouvre ce nouveau fil pour plusieurs raison:

- suite à une discussion animée d'hier soir sur le forum Webrankinfo ou il était question de partage de connaissances, de pédagogie, d'aciens et de nouveaux wrinautes (j'espère quen tant que nouveau, j'apprendrais quelque chose aux anciens pour pas qu'ils se barrent! :wink: )
- parce que 'j'ai vu plusieurs fils ou les webmasters s'interrogent sur le passage du mutualiser au dédié (l'astuce que je donne ici permet de soulager énormément le serveur)

Si le truc que je vous communique est déjà archi connu, vous avez le droit de m'insulter!

Voila, sur tous mes sites et ceux de mes clients, j'utilise une mise en cache des pages PHP sous forme de page HTML (non, ce n'est pas pareil que générer un site en HTML statique à partir d'un site dynamique!).

Je vous donne le code plus bas. :idea:

Pourquois procéder de la sorte? tout simplement pour limiter le nombre de requetes mysql (grosses consommatrices de ressources CPU). Pour ceux qui ont du mal à comprendre, cela permet d'eviter le 'too many connection'. Bon si vous êtes sur un mutualisé, ça ne peut être efficace que si tout le monde fait de même. Par contre, sur mes serveurs dédiés, à serveur et traffic équivalent, je double le nombre de sites hébergés!

Code: Tout sélectionner
[i]ici code php que vous ne voulez pas mettre en cache[/i]
<?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
$fichierCache="cache/cache".$urldemandee; // 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é
   ob_start(); // on démarre la bufferisation de la page: rien de ce qui suit n'est envoyé au navigateur
?>
[i]Votre page PHP ici[/i]
<?php
   $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éjà
  include ($fichierCache); // on le copie ici
}
?>


Que fait ce script:

1/ il recupere l'url de la page
2/ transforme cet url en un nom de fichier sans /
3/ teste l'existance de ce fichier dans le répertoire /cache/
4/ si le fichier n'existe pas, génére la page, puis la stoque dans le repertoire cache
/5 si le fichier existe, l'ouvre en tant que page html

La page html est générée lors de la premiere requete. Avce ce système, il faut gerer le cache lors des mises à jour (effacer la page du cache correspondante).

Je gere un site de + de 80 000 pages avec ce système sans problème notoire!

Voila!

si vous êtes sages et que ce fil a du succé, je vous filerez une autre astuce de temps en temps.
Code: Tout sélectionner
Modifié en dernier par fandecine le Mer Mai 18, 2005 15:01, modifié 3 fois.
Haut
326 Réponses
Messages: 414

Enregistré le: 15 Juin 2004

Message le Mar Mai 17, 2005 15:34

Merci pour ce code! Même si je n'ai pas encore de problèmes au niveau des performances de mon hébergement, j'essaierai de mettre en place ce système, mieux vaut prévenir que guérir :wink:
Si j'ai bien compris, tu te sers de cette ligne:
Code: Tout sélectionner
if (@filemtime($fichierCache)<time()-(3600*24*360))

pour spécifier la durée d'expiration d'un fichier cache, et si je sais bien calculer, là il est spécifié que si le fichier a moins d'un an d'existence, on ne le rafraîchit pas. C'est bien ca?
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 15:42

c'est ça! :D
Haut
Messages: 414

Enregistré le: 15 Juin 2004

Message le Mar Mai 17, 2005 15:51

Il y a même possibilité d'améliorer ton script: dans spip (qui propose aussi un système de cache), chaque page peut être rechargée grâce à un paramètre GET recalcul, il suffirait de faire:
Code: Tout sélectionner
if (@filemtime($fichierCache)<time()-(3600*24*360) || isset($_GET['recalcul']))

pour ne pas avoir à se connecter en ftp et supprimer le fichier pour faire une mise à jour... on aurait qu'à appeller la page avec ce paramètre recalcul.
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 15:55

j'y avais pensé, mais quand je fais des mises à jour, ça concernne parfois des centaines de pages et là le ftp est imbatable!
Haut
Messages: 871

Enregistré le: 21 Juil 2003

Message le Mar Mai 17, 2005 16:09

merci fandecine c'est énorme, ça fait un moment que je voulais m'y mettre.

par contre pour faire la casse pieds, tu pourrais pas mettre en anotation le rôle de chaque ligne avec des "//" comme ça ce serait plus facile à comprendre.
à partir de "ob_start(); " je suis complètement perdue :oops:

merci
carole
Haut
Messages: 8614

Enregistré le: 14 Mai 2003

Message le Mar Mai 17, 2005 16:12

Salut,

Moi aussi j'utilise du cache HTML, il n'y a rien de tel :)

Mais avec des templates à la "Smarty" sauf que c'est du PHP PUR !
Pas besoin de réinventer la roue, PHP est parfait pr les templates ;)

Je ne coupe plus la page en header/footer comme l'on ferais avec des pseudo templates PHP, c'est bcp plus simple à modifier le "layout".

Le tuto sur lequel je me suis basé:
http://www.massassi.com/php/articles/template_engines/

Je ne remercierais jamais assez Brian Lozier d'avoir montré cette superbe alternative à Smarty... j'étais parti pour utiliser Smarty puis je suis tombé là dessus...
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 16:28

caro a écrit:par contre pour faire la casse pieds, tu pourrais pas mettre en anotation le rôle de chaque ligne avec des "//" comme ça ce serait plus facile à comprendre.


meuh non! t'es pas casse pieds carole! :D

je t'ai rajouté tout plein de commentaires.
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mar Mai 17, 2005 16:54

Exactement se que je suis en train de mettre en place depuis trois jours sur mes sites ;-)

C'est génial :-)

Et avec un dédié on peut en plus coupler ça avec d'autres caches (sql, php accelerator)
Haut
Messages: 37718

Enregistré le: 7 Juil 2004

Message le Mar Mai 17, 2005 16:56

fandecine l'astuce est très interessante et j'imagine que ohax va débarquer pour en donner son opinion :lol:
sinon les pavés je suis pas trop fans mais c'est très gentil de mettre cette formule que jai lu directement et que j'apprécie beaucoup ;)
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mar Mai 17, 2005 17:16

Il manque la supression du cache...

En fait il faudrait expliquer comment supprimer les fichiers si on modifie la page plutot que d'attendre la fin du temps de cache ça permettrai de l'appliquer à un forum par exemple, ou à un blog ;-)
Haut
Messages: 8614

Enregistré le: 14 Mai 2003

Message le Mar Mai 17, 2005 17:20

Pour la suppression du cache:
La solution que l'on pense de suite:

Code: Tout sélectionner
exec("rm -f /home/user/public_html/cache/*");


Mais lorsque l'on se retrouve avec beaucoup de fichiers dans un répertoire, il y'a une limitation quelque part dans le kernel linux pour le nombre de fichiers, alors la commande ci-dessus ne fonctionneras plus.

La solution ultime:
Code: Tout sélectionner
exec("find /home/user/public_html/cache/ | xargs rm");
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 17:34

hola! j'avais dit une astuce à la fois! :wink:

bon, prenons un cas concret. Sur le site de mon profil, je vais, cette nuit :cry: , malgrés la fatigue metre à jour la page des sorties en salles (mais aussi des sorties de la semaine prochaine, ajouter des films, des affiches etc...). J'efface le cache en FTP avec une routine du style de celle-ci:

Code: Tout sélectionner
<?php
   $conn_id = ftp_connect("ftp.monsite.com");
   $login_result = ftp_login($conn_id, "loginftp", "passwordftp"); //connection ftp
   @ftp_site ($conn_id, "CHMOD 777 chemin_vers_le_fichier_a_effacer"); // on change les droit sur le fichier pour pouvoir l'effacer
   @ftp_delete ($conn_id, "chemin_vers_le_fichier_a_effacer
"); // on efface le fichier
   //si plusieurs fichiers à effacer
   foreach (glob("chemin_vers_les_fichiers_a_effacer-*.html") as $filename) { // liste des fichiers correpondants au masque
      @ftp_site ($conn_id, "CHMOD 777 ".$filename);
      @ftp_delete ($conn_id, $filename);
   }
   ftp_quit($conn_id);
?>


N.B: Le ficheir cache est crée par un script PHP, donc avec les attributs groupe et owner egale à PHP. Le fichier cache est supprimé en FTP donc avec l'attribut loginftp! c'est pour cela qu'il faut d'abord changer les droits du fichier à effacer en 0777 pour pouvoir l'effacer.

Voila, c'est un script trés parcellaire car il est trop dépendant de la structure du site, mais couplé à une BDD et une requete mysql c'est trés puissant!
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mar Mai 17, 2005 17:39

Et je crois que tu as oublié de préciser que c'est un cache d'un an non?

3600*24*360
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 17:59

en fait j'ai mis un an pour etre sur que le fichier ne soit pas regénéré avant un moment, mais je suis actuellement en train de valider ma BDD enregistrement par enregistrement et dans l'avenir, je donnerais une durée de vie infinie aux fichier cache valides (aucune raison de les générer à nouveau).

Un enregistrement (par exemple un film) est validé lorsque j'ai toutes les infos (casting, synopsis, durée etc...) et toutes les ressources annexes (wallpapers, bande annonce, jaquettes...) A ce moment là, la fiche n'étant plus mise à jour, aucune raison d'effacer le cache.

Par contre, lorsque je modifie le code des pages, je renome le répertoire cache (en connexion SSH) puis j'en recré un vide et hop, ça reppart.

PS: si vous avez des questions, faudrat attendre demain car j'ai un RDV... a demain :D
Haut
Messages: 153

Enregistré le: 26 Sep 2003

Message le Mar Mai 17, 2005 20:28

marrrant, j'ai implémenté le même système il y a un an pour le site de mon boulot :)
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mar Mai 17, 2005 21:29

Code: Tout sélectionner
<form action="<?php dcPostUrl(); ?>" method="post" id="comment-form">
<fieldset>


j'ai ça dans une page, et dans le cache <?php dcPostUrl(); ?> = rien du tout.

en gros dans le cache ça me donne:

Code: Tout sélectionner
<form action="" method="post" id="comment-form">
<fieldset>


une idée du pourquoi du comment?
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 22:06

peut-tu nous donner le source de la fonction dcPostUrl()
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mar Mai 17, 2005 22:16

Code: Tout sélectionner
@function dcPostURL

Cette fonction affiche l'URI du billet, son permalien. On l'utilisera dans
l'affichage d'un billet (boucle ou pas). Par exemple:

|<a href="<?php dcPostURL(); ?>">lien permanent</a>
*/
function dcPostURL()
{
   echo $GLOBALS['news']->getPermURL();
}



et bien sur je suis allé cherché après getpermurl:

Code: Tout sélectionner
# Lien permanent vers le commentaire
   function getPermURL()
   {
      $post_titre_url = $this->blog->str2url($this->f('post_titre'));
      
      $url = sprintf($this->blog->front_url['post'],$this->f('postyear'),
               $this->f('postmonth'),$this->f('postday'),
               $this->f('post_id'),$post_titre_url);
      
      return $url.'#c'.$this->f('comment_id');
   }
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mar Mai 17, 2005 22:31

là, ça se corse! y a des variables partout! Faudrait voir le code complet. Si ça te pose vraiment de gros problèmes envoie moi le code par mp, je regarde ça demain.
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mer Mai 18, 2005 0:26

Je trouve le code assez mal fait en fait... Peut etre parsque j'ai pas tout comprit mais:

Votre page PHP ici

moi cette partie je l'aurai mit dans

if ($fd) {

en adaptant histoire de n'executer le code php QUE SI LE CACHE n'existe pas, car la j'ai l'impression que tu l'executes de toute façon non?
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mer Mai 18, 2005 0:37

pourtant, j'ai mis les commentaires JeunZ! Tu est fatigué ou tu me teste?

le secret c'est ob_start(); à partir de la, tout ce qui suit n'est pas envoyé au navigateur mais bufférisé.

ensuite, ob_get_contents() récupére le contenu du buffer, on peut alors areter la bufferisation avec ob_end_flush() et sauvegarder le contenu dans le fichier cache.

simple, non?
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mer Mai 18, 2005 0:57

Je suis d'accord (je suis pas un pro je vais sans doute dire une connerie, surtout que je n'ai jamais utilisé cette histoire de buffer), mais même si ce n'est pas envoyé au navigateur c'est executé coté serveur non?

(aie ca y est je crois que j'ai dit la connerie).
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mer Mai 18, 2005 1:11

Forcement, c'est du php. :wink:
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mer Mai 18, 2005 2:00

Et bien alors si on met une condition sur l'existance du fichier cache on peut ne pas executer le code php et ainsi économiser des ressources serveurs.


Si cache alors on met le cache sinon on execute le code php et on génère le cache.


C'est mieux que :

On execute le code php, si le cache existe on affiche le cache sinon on génère le cache et on affiche le code php.


Dans la seconde solution celle présentée ici on execute toujours le code php alors que dans un cas c'est inutile je crois.
Haut
Messages: 742

Enregistré le: 13 Oct 2004

Message le Mer Mai 18, 2005 8:24

Vous savez que JP-Cache fait tout cela tres bien, rapidement et depuis tres longtemps ? ;)
Haut
Messages: 414

Enregistré le: 15 Juin 2004

Message le Mer Mai 18, 2005 8:26

Code: Tout sélectionner
if (@filemtime($fichierCache)<time()-(3600*24*360)) { //si la page existe dans le cache et n'a pas expirée
   ob_start(); // on démarre la bufferisation de la page: rien de ce qui suit n'est envoyé au navigateur
?>
[i]Votre page PHP ici[/i]
<?php
   $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éjà
  include ($fichierCache); // on le copie ici
}

Jeunz -> c'est ce qu'il fait. Avant de buffériser, il teste si le cache n'est pas expiré, si c'est le cas il fait le include du fichier en cache, sinon il exécute le code en le bufférisant
Haut
Messages: 5288

Enregistré le: 18 Fév 2004

Message le Mer Mai 18, 2005 11:02

Ba alors je comprend pas car avec la méthode ci dessu testé hier pendant 3h la charge de mon dédié n'a pas changé par contre j'avais un affichage un peu plus rapide.

J'ai fait ma modif, et ma charge est depuis lors divisée par 10...
Haut
Messages: 414

Enregistré le: 15 Juin 2004

Message le Mer Mai 18, 2005 11:31

Tu peux mettre ta modification? Est-ce que tu as pu constater que des fichiers étaient créés dans le répertoire cache?
C'est bizarre, parce que dans la logique du script de fandecine, il n'exécute le php que si le fichier est expiré...
Haut
Messages: 2191

Enregistré le: 2 Avr 2005

Message le Mer Mai 18, 2005 11:34

Attention! Si la page PHP que tu met en cache consomme peu de resources, tu vera pas de changement notoire de charge. Par contre si ttu fait un max de requettes Mysql, y a pas photo ni sur la vitesse de chargement, ni sur la charge du serveur.

Par exemple, lorsque je fais une grose Maj sur mon site, je peux te dire que je vois la charge grimper en fleche jusqu'a ce que le cahe soit regénéré.

Maintenent je serais curieux de voir ton code modifié!?
Haut

Formation recommandée sur ce thème :

Formation SEO spéciale Wordpress : apprenez à optimiser le référencement naturel d'un site fait avec Wordpress... Formation Ranking Metrics animée par un expert SEO / Wordpress.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.