web-dev-qa-db-fra.com

Comment obtenir le navigateur pour cache des images, avec PHP?

Je suis totalement nouveau pour mettre en cache des images.

Je publie toutes les images d'une galerie avec PHP et que vous voulez que les images déjà affichées doivent être caches par le navigateur, de sorte que le PHP n'a pas à sortir la même image. Tout ce que je Vous voulez que les images se présentent plus rapidement.

Lorsque vous appelez une image, je fais comme ceci:

<img src="showImage.php?id=601">

et le showImage.php- Fichier fait:

$id = (int) $_GET['id'];
$resultat = mysql_query("
    SELECT filename, id
    FROM Media 
    WHERE id = $id
");
$data = mysql_fetch_assoc($resultat);

...

//Only if the user are logged in
if(isset($_SESSION['user'])){
    header("Content-Type: image/jpeg");

    //$data['filename'] can be = dsSGKLMsgKkD3325J.jpg
    echo(file_get_contents("images/".$data['filename']."")); 
}
24
Johan

Si vous utilisez PHP pour vérifier si l'utilisateur est connecté avant de sortir le message, vous ne voulez pas que le navigateur cache l'image.

L'ensemble du point de cache est d'appeler le serveur une fois, puis de ne plus jamais l'appeler. Si le navigateur met en cache l'image, il n'appellera pas le serveur et votre script ne fonctionnera pas. Au lieu de cela, le navigateur tire votre image du cache et l'affiche, même si l'utilisateur n'est plus connecté. Cela pourrait potentiellement être un très grand trou de sécurité.

5
Imagist

Tout d'abord, si vous utilisez des sessions, vous devez désactiver session_cache_limiter (en le réglant à none ou public). Les en-têtes envoient sont plutôt mauvais pour les caches.

session_cache_limiter('none');

Ensuite, envoyez Cache-Control: max-age=number_of_seconds et éventuellement un équivalent Expires: entête.

header('Cache-control: max-age='.(60*60*24*365));
header('Expires: '.gmdate(DATE_RFC1123,time()+60*60*24*365));

Pour la meilleure cache-câble, envoyer Last-Modified En-tête et réponse avec statut 304 et corps vide si le navigateur envoie une correspondance If-Modified-Since entête.

header('Last-Modified: '.gmdate(DATE_RFC1123,filemtime($path_to_image)));

Pour une brièveté, je triche ici un peu (l'exemple ne vérifie pas la date), mais elle est valide tant que cela ne vous dérange pas de naviguer sur le fichier mis en cache pour toujours:

if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
   header('HTTP/1.1 304 Not Modified');
   die();
}
49
Kornel

Voici un certain code que j'utilise pour le support d'en-tête 304:

  /**
   * @return false if not cached or modified, true otherwise.
   * @param bool check_request set this to true if you want to check the client's request headers and "return" 304 if it makes sense. will only output the cache response headers otherwise.
   **/     
  protected function sendHTTPCacheHeaders($cache_file_name, $check_request = false)
  {
    $mtime = @filemtime($cache_file_name);

    if($mtime > 0)
    {
      $gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
      $etag = sprintf('%08x-%08x', crc32($cache_file_name), $mtime);

      header('ETag: "' . $etag . '"');
      header('Last-Modified: ' . $gmt_mtime);
      header('Cache-Control: private');
      // we don't send an "Expires:" header to make clients/browsers use if-modified-since and/or if-none-match

      if($check_request)
      {
        if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && !empty($_SERVER['HTTP_IF_NONE_MATCH']))
        {
          $tmp = explode(';', $_SERVER['HTTP_IF_NONE_MATCH']); // IE fix!
          if(!empty($tmp[0]) && strtotime($tmp[0]) == strtotime($gmt_mtime))
          {
            header('HTTP/1.1 304 Not Modified');
            return false;
          }
        }

        if(isset($_SERVER['HTTP_IF_NONE_MATCH']))
        {
          if(str_replace(array('\"', '"'), '', $_SERVER['HTTP_IF_NONE_MATCH']) == $etag)
          {
            header('HTTP/1.1 304 Not Modified');
            return false;
          }
        }
      }
    }

    return true;
  }
7
KiNgMaR

Vous pouvez stocker les images générées dans un répertoire appelé "showImage" afin que vous les incorporiez comme ça

<img src="showimage/601.jpg" />

Ensuite, vous placez un . Fichier htack dans le même répertoire qui appellera showImage.php? ID = au cas où le fichier n'existe pas, E.G.:

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)\.jpg$ showImage.php?id=$1 [QSA,L]
</IfModule>

Il suffit de lire dans votre commentaire que vous souhaitez faire la mise en cache du côté client: il suffit de définir les en-têtes HTTP liés à la mise en cache conformément à http://www.mnot.net/cache_docs/

4
middus

S'il vous plaît ne pas adresser des images sont une ressource ID'ed. Utilisez des URL absolues pour les images, de préférence dans un sous-domaine, de préférence de la cookie moins. Le navigateur fera la mise en cache sur les images. Un truc soigné pour charger des images plus rapidement sur des sites Web consiste à le mettre sur certains CDN ou autre site. Ceci parce que les navigateurs limitent le nombre de threads de demande parallèle à un domaine.

Une autre façon nette de travailler avec des images est la source, le regarde. Cela permet d'économiser beaucoup de bande passante et des demandes également.

Vous pouvez également utiliser un chargement de bitmap direct si la vitesse est si cruciale. Ceci n'est pas conseillé pour les grandes images cependant. Si ses icônes et ses petites images/gifs que vous chargez. Vous pouvez utiliser des bitmaps directement sur la page.

1
Ritesh M Nayak