Aller au contenu

Gestion de cache, pb de headers


Sujets conseillés

Posté

Salut,

Je cherche à mettre en place une gestion de cache intelligente fonctionnant sur le principe suivant :

1) Toute requète de page html est redirigée vers page.php

1.1) si la page demandée fait partie de l'ensemble des pages "articles" (les pages qui sont mises en cache) :

1.1.1) si elle existe en cache, je compare sa date de dernière modification à l'en-tête "if-modified-since"

1.1.1.1) si les dates correspondent, je veux renvoyer un code "304 not modified", sans renvoyer la page

1.1.1.2) sinon, je dois renvoyer la page en spécifiant son header "last-modified" (en la gzippant au assage histoire d'économiser la bande passante)

1.1.2) si elle n'existe pas en cache, je la génère, je la stocke en cache, et je la renvoie en spécifiant son header "last-modified"

Pb : Je n'obtiens jamais une réponse 304 quand je consulte une page, et je n'arrive pas à récupérer le paramètre "if-modified-since". Je renvoie donc systématiquement la page, et je préfèrerais éviter. Si quelqu'un qui a déjà été confronté à cette problématique pouvait me donner des pistes, ce serait super (me manque-t-il des headers par exemple).

Ci-après mon code de test

if (file_exists ($cache_file))
{
$if_modified_since = preg_replace('/;.*$/', '', $HTTP_IF_MODIFIED_SINCE);
$mtime = filemtime($cache_file);
$gmdate_mod = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
if ($if_modified_since == $gmdate_mod)
{
header ("HTTP/1.0 304 Not Modified");
exit;
}
header("Last-Modified: $gmdate_mod");
ob_start("ob_gzhandler");
readfile ($cache_file);
ob_end_flush();
}
else
{
file_put_contents ($cache_file, "Je suis l'article $id créé le " . date ("d/m/Y h:i:s") . "<hr />" . file_get_contents ("lipsum.txt"));
ob_start("ob_gzhandler");
readfile ($cache_file);
ob_end_flush();
}

Posté

Hello,

tu es certain que le register_globals est activé ? si ce n'est pas le cas $HTTP_IF_MODIFIED_SINCE sera toujours vide...

De manière générale, active l'affichage des erreurs... ne serait ce que pour débugger, c'est essentiel : error_reporting( E_ALL | E_STRICT );

Et essayes de te passer de register_globals : $_SERVER['HTTP_IF_MODIFIED_SINCE'].

Sinon, si j'ai bonne mémoire je t'avais déjà conseillé de remplacer ob_start('ob_gzhandler') par un ini_set('zlib.output_compression', true) qui consomme moins de mémoire et induit moins de "latence" dans l'envoi de la page.

===

Sinon pendant qu'on y est :

*) une autre solution serait de rediriger uniquement les 404 vers ton script PHP. Ainsi Apache/Lighty/NginX/autre gèrerait la mise en cache de son coté, de manière plus fiable et plus rapide qu'un script PHP.

*) dans ton script actuel, pourquoi faire un "readfile()" du contenu que tu viens d'écrire, et pas simplement un echo ?

*) le code correspondant à la compression du contenu est commun aux deux cas de ton if, donc pourquoi ne pas le sortir du if justement ? Ca t'éviterait la duplication de code.

*) le code header("HTTP/1.0 304 Not Modified"); n'est pas compatible avec un PHP en (fast)CGI.

Posté (modifié)

Alors :

  • J'ai essayé avec $_SERVER ["HTTP_IF_MODIFIED_SINCE"], ça ne donne rien (la valeur n'y est d'ailleurs pas quand je fais un print_r ($_SERVER))
  • Pour le ob_gzhandler, c'est pas faux. C'est du code récupéré à droite à gauche, j'aurais modifié ça plus tard.
  • Pour la duplication de code, j'avais vu ça dans l'intervalle :)
  • Pour le readfile, tu as raison à 100% (ah ces copier-coller de code entre 2 paragraphes :D)
  • Je ne peux malheureusement pas prendre que les 404 pour l'instant en raison de l'architecture, et puis ça enlèverait l'avantage de la compression (à moins qu'on puisse stocker les pages sous forme compressée, ce que j'ignore)
  • Et pour le header 304, existe-t-il une méthode qui marcherait en fast-cgi ?

Modifié par MarvinLeRouge
Posté

$_SERVER ["HTTP_IF_MODIFIED_SINCE"] : si le navigateur l'envoi, il devrait être présent (à vérifier avec Live HTTP Headers sous Firefox).

S'il n'est pas envoyé, c'est probablement à cause d'entêtes Cache-Control ou Pragma qui ne correspondent pas... tu utilises les sessions sur la page en question ?

404 / compression : les serveurs Web gèrent parfaitement la compression à la volée, c'est d'ailleurs probablement déjà activé pour tes fichiers CSS et JS non ?

304 : oui, il suffit d'ajouter un "IF" :

// A cause d'un "bug" de PHP il faut désactiver la compression avant d'envoyer une réponse 304
ini_set('zlib.output_compression', false);

if( substr(php_sapi_name(), 0, 3) === 'cgi' )
header('Status: 304 Not Modified');
else header('Not Modified', true, 304);

exit;

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...