Système de cache, comment le mettre en place ?

Système de cache, comment le mettre en place ? - PHP - Programmation

Marsh Posté le 13-01-2009 à 18:00:19    

Bonjour,  
Je veux mettre en place un système de cache pour les pages de mon site.
J'ai terminé mais çà ne me convient pas du tout : le fonctionnement actuel, revient à déterminer la durée de vie de la page (ici, 3600 secondes) et si celle-ci est dépassée, alors je construis ma page dynamiquement de la façon habituelle, puis grâce à ob_get_contents, j'enregistre la page dans un fichier "cache".
Si au contraire la durée de vie n'est pas dépassée, alors je lit ce fichier "cache", tout simplement.
Problème : le fichier cache contient toutes mes données, du "<html>" au "</html>", absolument tout. Cela ne peut pas convenir, si, par exemple, j'ajoute un espace membre, comme je prévois de le faire, parce que la page mise en cache correspondrait exactement à celle de la dernière personne a s'être connectée alors que le cache n'était plus à jour...
 
Je ne sais pas comment faire puisque les requêtes BDD se font à la construction de mon objet Page qui contient les informations sur la page appelée...
 
Le code (commenté) :
 

Code :
  1. <?php
  2. // appel des fichiers inclus.
  3. $id = (ctype_digit(@$_GET['id'])) ? (int) @$_GET['id'] : NOT_CORRECT_PAGE;
  4.  
  5. $enable_cache = (isset($_GET['cache'])) ? (bool) $_GET['cache'] : true;
  6. $cache  = "page-$id.html";
  7. $expire = time() - 3600;
  8.  
  9. if(file_exists($cache) && filemtime($cache) > $expire && $enable_cache === true) {
  10.     echo file_get_contents($cache);
  11.     exit();
  12. }
  13.  
  14. // Liste des pages pour le sommaire
  15. $pageList = new PageList();
  16. $pageList = $pageList->getMenu();
  17.  
  18. // Liste des catégories : toujours pour le sommaire
  19. $categoryList = new CategoryList();
  20. $categoryList = $categoryList->get();
  21.  
  22. if($id) {
  23.     $page = new Page(array('id' => $id));
  24. } else {
  25.     $page = new Page(array('id' => NOT_CORRECT_PAGE));
  26. }
  27.  
  28. /* Construction de la page : à l'appel de getPage(), la requête SELECT est envoyée et
  29. l'objet est rempli */
  30. $success = $page->getPage();
  31.  
  32. if(!$success) {
  33.     $page = new Page(array('id' => NOT_FOUND_PAGE));
  34.     $page->getPage();
  35. }
  36.  
  37. ?>
  38. <!-- Generation : <?php echo @date('H:i:s', time()) . ' on ' . @date('d/m/y', time()); ?>-->
  39. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  40. <html xmlns="http://www.w3.org/1999/xhtml">
  41. <head>
  42. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  43. <title><?php echo TITLE.$page->getTitle() ?></title>
  44. <link rel="stylesheet" href="style.css" media="all" />
  45.  
  46. </head>
  47.  
  48. <body>
  49. <div id="header">
  50. <?php echo HEADER ?>
  51. </div>
  52.  
  53. <div id="main">
  54. <div id="colonne1">
  55. <ul class="menu">
  56. <?php
  57. $old_category = 0;
  58.  
  59. foreach($pageList as $current) :
  60.     $category = $categoryList[$current->getCategory()];
  61.     if($old_category != $category->getId()) :
  62.         ?><li><?php echo $category->getName(); ?></li><?php
  63.     endif;
  64.     $old_category = $category->getId();
  65.     ?>
  66.     <li> - <a href="page.php?id=<?php echo $current->getId() ?>"><?php echo stripslashes($current->getTitle()) ?></a></li>
  67.    <?php endforeach; ?>
  68. </ul>
  69. </div>
  70.  
  71. <div id="colonne2">
  72. <?php include 'sidebar2.php' ?>
  73. </div>
  74.  
  75. <div id="centre">
  76. <h3><?php echo $page->getName() ?></h3>
  77.  
  78. <?php echo bbcode(stripslashes(nl2br(htmlspecialchars($page->getContent())))) ?>
  79. </div>
  80. </div>
  81. <div id="footer">
  82. Lucas GAUTHERON &copy; 2008 - <a href="http://validator.w3.org/check?uri=referer&amp;charset=(detect+automatically)&amp;doctype=Inline&amp;group=0&amp;user-agent=W3C_Validator%2F1.606">xHTML Valid</a> | <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer&amp;profile=css21&amp;usermedium=all&amp;warning=1&amp;lang=fr">CSS Valid</a> | <?php echo round(microtime(true) - $t, 6); ?> secondes.
  83. </div>
  84. </body>
  85. </html>
  86. <?php
  87. $output = ob_get_contents();
  88. file_put_contents($cache, $output);
  89. echo $output;
  90. ?>


 
Si vous avez des idées, n'hésitez pas ! Merci d'avance !

Reply

Marsh Posté le 13-01-2009 à 18:00:19   

Reply

Marsh Posté le 14-01-2009 à 20:11:42    

up :o

Reply

Marsh Posté le 14-01-2009 à 21:45:33    

perso  ,j'en mettrai moins en cache, mais je le mettrai en cache ram avec memcached
 
et je ne mettrai en cache que les goulet d'etranglement du site : requete sql trop gourmande et pas optimisable par exemple


---------------

Reply

Marsh Posté le 15-01-2009 à 00:12:43    

Luc@s : la solution à ton probleme est de continuer a faire exactement ce que tu fais mais à la faire par morceau.
 
Je m'explique, en effet si tu as par exemple un espace membre tu aura un morceau de HTML type "<h1>Bienvenue Luc@s</h1>" et il est hors de question de mettre ça en cache.
 
Donc ce morceau de code sera ds un autre include ou require et toi tu gère tes morceau de cache par include et par require.
 
N'hésites pas à me demander si je m'explique mal ;)

Reply

Marsh Posté le 15-01-2009 à 10:15:39    

ou mettre

Code :
  1. "<h1>Bienvenue <?php echo $login ?></h1>"

dans le cache ?


---------------
oui oui
Reply

Marsh Posté le 15-01-2009 à 18:06:06    

[:canaille]  
 
@flo : pour memcached : c'est une extension si j'ai bien compris ? Le problème c'est que je ne peux pas intégrer d'extension pour ce projet :(
 
@yellu : aurais-tu un exemple ?
 
@art_dupond : mais il va enregistrer le login dans le cache  :(
 
Merci pour vos réponses ;)


Message édité par Profil supprimé le 15-01-2009 à 18:06:26
Reply

Marsh Posté le 15-01-2009 à 18:09:21    

meme sans memcached, il y a très peu de bonne raison de mettre tout le site en cache, l'évalution d'une page php basique à un coût ridicule , et peu même être moins couteux qu'un accès disque de plus  
 
on ne cache que ce qui permet de gagner du temps , là où c'est nécessaire


---------------

Reply

Marsh Posté le 15-01-2009 à 18:17:38    

comme il s'agit de pages gérées dynamiquement et que le temps d'exécution va jusqu'à 100 ms (grand max) et que mon site est vraiment ralenti quand il s'agit de scripts qui sollicitent mysql j'avais décidé de faire un système de cache (qui divise par 4 le temps de chargement dans certains cas en ligne, mais avec bcp moins de différence en local).
Aussi ces pages sont rarement mises à jour.
Mais je pense que je vais le retirer, terminer l'espace membres et je verrais après.
;)

Reply

Marsh Posté le 15-01-2009 à 18:37:25    

Luc@s, voici un exemple :
 
Au lieu d'avoir ta page en 1 seul bloc comme tu l'as montré ici, tu la segmente en plusieurs morceaux avec des  
 
include 'header.php';
include 'milieu.php';
 
etc...
 
ensuite tu modifies ton include_path en y mettant en premier lieu un repertoire 'cache/'.
 
Ceci aura pour effet que lors des includes de header.php, milieu.php, PHP ira d'abord voir si le fichier existe dans le repertoire cache/ avant d'inclure le vrai fichier.
 
Dans les vrais fichiers tu fais ta petite méthode avec ob_start qui génère une copie dans le répertoire cache/.
 
Tu place une crontab qui vide le répertoire cache toute les X minutes et normalement ça devrait fonctionner je pense.
 
A toi de choisir ensuite quels include tu caches ou non (ceux avec de la personnalisation SESSION, non par exemple).
 
Mon plan a peut être une faille, mais j'espère que ça pourra te mener à une piste :)


Message édité par yellu le 15-01-2009 à 18:39:27
Reply

Marsh Posté le 15-01-2009 à 18:38:57    

ah ok je vois où tu veux en venir, pour l'instant je vais supprimer mon système de cache, que je repousse à plus tard dans le projet mais j'essaierais ta solution ;) merci à tous

Reply

Marsh Posté le 15-01-2009 à 18:38:57   

Reply

Marsh Posté le 16-01-2009 à 13:46:07    

$smarty->caching = 1.
De rien.[:doc petrus]


Message édité par skeye le 16-01-2009 à 13:46:13

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 16-01-2009 à 18:02:30    

Et si je veux pas utiliser smarty [:dawa]

Reply

Marsh Posté le 16-01-2009 à 18:14:41    


tu réinventes la roue, je suppose, comme tout le monde.[:petrus75]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 16-01-2009 à 18:19:09    

skeye a écrit :


tu réinventes la roue, je suppose, comme tout le monde FlorentG.[:petrus75]


 :o  
 
Plus sérieusement je n'envisage pas de système de template pour l'instant...

Reply

Marsh Posté le 17-01-2009 à 11:08:18    

j'ai adapté mon fichier page.php à smarty et çà marche plutôt bien, j'ai tout de même eu des difficultés pour le sommaire.
Ceci dit j'ai toujours le même pb pour le système de cache, enfin il n'a pas grande utilité.

Reply

Marsh Posté le 17-01-2009 à 11:12:59    

Pour ton problème, je te conseille d'utiliser un système de cache similaire à celui utilisé par Rails. Voilà un tutorial de Rails, tu peux regarder comment ça fonctionne et faire quelque chose de similaire (ce qui te concerne c'est surtout l'utilisation des sweepers et le action caching : http://www.railsenvy.com/2007/2/28 [...] g-tutorial )


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 17-01-2009 à 11:29:35    

ok, merci.

Reply

Marsh Posté le 17-01-2009 à 13:19:39    


comment ça pas grande utilité??
Tu peux invalider le cache quand tu le souhaites, mettre en cache tout ou partie de tes pages, avoir plusieurs versions d'un même template en cache...il te faut quoi de plus?[:pingouino]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 17-01-2009 à 13:33:46    

Je pense qu'il cherche pas un framework, il veut faire tout tout seul en se disant que ça sera mieux fait ... ça me rappelle ce que moi je pensais avant de commencer à utiliser Rails :bounce:


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 17-01-2009 à 13:37:54    

skeye a écrit :


comment ça pas grande utilité??
Tu peux invalider le cache quand tu le souhaites, mettre en cache tout ou partie de tes pages, avoir plusieurs versions d'un même template en cache...il te faut quoi de plus?[:pingouino]


 
tu m'as mal compris ou je me suis mal exprimé : un système de cache n'a pas grande utilité pour mon site.
 
@esox_ch : oui je préfère un système de cache perso

Reply

Marsh Posté le 21-01-2009 à 11:48:11    

Donc je résume : tu veux créé un système de cache pour ton site par ce qu'un système de cache n'a pas encore une grande utilité pour ton site.  :pt1cable:  
 
Entre nous, il vaut mieux avoir dessuite quelque chose de souple et puissant même si on utilise au début que 1% de ses capacités qu'avoir un système qui fait uniquement ce qu'on voulait au départ mais qu'on doit refaire plusieurs fois de zéro par ce qu'on a eu besoin de plus souple quelques mois plus tard.
Là dessus tu peux me croire les yeux fermé, c'est le genre d'erreur que j'ai fait plusieurs fois. ;)

Reply

Marsh Posté le 21-01-2009 à 14:52:34    

je te crois, passer à smarty m'a pris pas mal de temps, je crois que je vais faire plus attention...
Mais je change d'hébergeur (l'actuel est mauvais) et j'aurais je pense une rapidité d'exécution plus similaire à celle que je peux observer en local et donc je peux laisser tomber un système de cache.
Merci à tous pour vos réponses.

Reply

Marsh Posté le 28-01-2009 à 10:59:21    

Arf avec un mauvais hébergeur, mutualisé et des requetes > 100ms tu dois user du cache
dans ton cas, le plus logique est de créer des fichiers à partir des requêtes sql les plus gourmandes, mettre en cache des pages entières, cela ne sert à rien.
+ Ne pas oublier la requete SQL_CACHE qui peut parfois accélerer par 3 les résultats


---------------
Photos Panoramiques Montagnes Haute Savoie
Reply

Marsh Posté le 28-01-2009 à 11:09:24    

grosbin a écrit :

dans ton cas, le plus logique est de créer des fichiers à partir des requêtes sql les plus gourmandes,

 

A quel format? Un truc perso? Trop cool, la relecture du fichier + reconstitution du contenu pour regénérer le html va te couter plus cher que de refaire ta requête.

 
grosbin a écrit :

mettre en cache des pages entières, cela ne sert à rien.

 

D'où l'intérêt d'utiliser proprement un moteur de templates qui va mettre en cache uniquement les morceaux de page générés via des requêtes couteuses.[:moule_bite]

 
grosbin a écrit :

+ Ne pas oublier la requete SQL_CACHE qui peut parfois accélerer par 3 les résultats

 

mysqlG [:sadnoir]


Message édité par skeye le 28-01-2009 à 11:09:49

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 28-01-2009 à 13:55:36    

avec smarty et mon tout nouvel hébergeur, j'en suis à une moyenne de 30 ms donc le système de cache n'est pas indispensable, non :??:

Reply

Marsh Posté le 28-01-2009 à 14:14:00    


les chiffres on s'en bat un peu...si c'est agréable à naviguer ça suffit.:o


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 29-01-2009 à 18:55:18    

J'utilise la solution décrite par Yellu pour mon site perso.
Un moteur de template, ça rajoute une couche avec des choses qui pourraient être directement dans PHP... je trouve ça disgracieux.
Pour ce qui est données en RAM, la solution du memcache est plutôt efficace... mais non persistante. Et puis à moins d'un hébergement dédié, tu peux toujours rêver pour que ton hébergeur active ce module, pas fou non ? :)

Message cité 1 fois
Message édité par CyberDenix le 29-01-2009 à 18:55:49

---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 30-01-2009 à 19:16:34    

m'ouais :o, enfin mon problème c'est plutôt d'éviter de faire des accès aux BDDs pour construire mes pages, donc je voudrais savoir comment mettre çà en cache...
Plutot que d'éviter la génération du tpl.

Reply

Marsh Posté le 30-01-2009 à 19:23:51    

CyberDenix a écrit :

Un moteur de template, ça rajoute une couche avec des choses qui pourraient être directement dans PHP...


 
ne pas en utiliser, ça rajoute dans ton code php des choses que le moteur pourrait gérer tout seul :D


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 31-01-2009 à 14:31:45    

Moi perso mon probleme avec les templates PHP, c'est le métalangage qui lui est indéniablement une surcouche.
 
Dans la mesure ou PHP peut se méler au HTML via son système de balisage je prefere mettre un foreach dans ma vue plutot que d'avoir un <!-- LOOP BEGIN --> ou je sais pas quelle autre invention ...

Reply

Marsh Posté le 31-01-2009 à 14:36:28    

c'est vrai que c'est une couche supplémentaire, et que çà alourdit obligatoirement les perfs... Mais franchement, l'intégration de smarty dans mon projet çà a prit 1 journée, le temps de lire la doc (qui est très bien faite soit dit en passant) et d'adapter les anciens templates...
Et puis le temps que j'ai gagné pour mes modifs... C'est énorme. En plus tu peux visualiser facilement le rendu :/
 
J'ai juste eu un problème avec smarty : un bug de regex qui a paralysé mon site sans que je sache pourquoi. J'ai téléchargé une version qui était sortie entre temps et qui corrigeait le problème et c'était reparti.
 
En gros un système de template c'est bien mais pas n'importe lequel. Je ne m'embêterait pas à utiliser autre chose que smarty amha.


Message édité par Profil supprimé le 31-01-2009 à 14:37:43
Reply

Marsh Posté le 22-03-2009 à 18:51:00    

Je me permets de remonter mon Topic parce que j'ai une question :
Grâce à is_cached je peux en théorie mettre en cache la partie de la page qui m'intéresse.
Le problème c'est que comme vous pouvez le constater, j'ai un seule appel de display qui affiche un TPL.
Ce TPL contient deux includes qui appellent d'autres TPL que je ne souhaite pas mettre en cache.
Ma question est donc : est-ce que display concerne également les TPL inclus ? Y a-t-il d'autres moyens de résoudre ce problème que d'appeler 3 fois la méthode display() ?

Reply

Marsh Posté le 22-03-2009 à 19:36:21    


 
pas compris la question. [:dawak]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 22-03-2009 à 19:41:37    

si tu veux désactiver le cache pour un morceau du template, tu peux avec un register_block, avec ce genre d'astuce (exemple en bas) :

 

http://www.smarty.net/manual/en/caching.cacheable.php


Message édité par skeye le 22-03-2009 à 19:41:46

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 24-03-2009 à 14:05:57    

OK, çà a l'air intéressant mais...
is_cached concerne seulement le TPL passé en argument, ou bien même les TPL inclus via {include} :??:

Reply

Marsh Posté le 24-03-2009 à 14:10:38    


à tester en exercice. :D


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 24-03-2009 à 14:35:59    

Bon bah d'après mes tests, c'est l'ensemble qui est mis en cache donc impossible de dissocier le template principal des sous templates inclus (que ce soit avec is_cached, clear_cached, etc...)
Je vais devoir me faire 3 appels de display() à chaque fois [:icon14]

Reply

Marsh Posté le 24-03-2009 à 14:51:52    

 

bah non, tu mets le contenu de tes templates inclus dans un bloc dynamique, non?:o


Message édité par skeye le 24-03-2009 à 14:52:13

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 24-03-2009 à 15:13:35    

Donc dans ce cas j'utilise is_cached normalement ?

Reply

Marsh Posté le 24-03-2009 à 15:29:37    


à tester, mais ça devrait...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed