2009-09-06 18 views
20

Sono totalmente nuovo su come memorizzare le immagini nella cache.Come far entrare il browser nella cache delle immagini, con php?

Emetto tutte le immagini in una galleria con php e voglio che le immagini già mostrate siano memorizzate nella cache dal browser, in modo che lo script php non debba restituire la stessa immagine di nuovo. Tutto quello che voglio è che le immagini si presentino più velocemente.

quando si chiama un'immagine mi piace questo:

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

e la -file showImage.php lo fa:

$resultat = mysql_query(" 
    SELECT filename, id 
    FROM Media 
    WHERE id = '".$_GET['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']."")); 
} 
+0

Non sono sicuro di ciò che si sta cercando di realizzare, dalla tua domanda iniziale sembrava come se si stesse generando immagini al volo e ha voluto memorizza le immagini generate al primo caricamento e invia da disco sui carichi successivi. Stai parlando del caching del browser? –

+1

Perché stai usando uno script PHP comunque? – Gumbo

+0

Sì, voglio che il browser memorizzi l'immagine nella cache. – Johan

risposta

4

Se si utilizza php per verificare se l'utente è connesso prima di emettere il messaggio, non si desidera che il browser memorizzi l'immagine nella cache.

L'intero punto del caching è chiamare il server una volta e quindi non chiamarlo più. Se il browser memorizza l'immagine nella cache, non chiamerà il server e il tuo script non verrà eseguito. Invece, il browser estrarrà la tua immagine dalla cache e la visualizzerà, anche se l'utente non è più loggato. Potrebbe essere un buco molto grande per la sicurezza.

+0

Hm, questo è un buon punto. Ma sarebbe OK per memorizzare l'immagine un'ora dura. – Johan

+1

Anche un'ora non è sicura, tutto ciò che fa è sperare che gli hacker non tentino di hackerare in un dato momento. Tuttavia, da quello che posso vedere su http://www.mnot.net/cache_docs/#SCRIPT, sembra che tu possa forzare l'autenticazione con il caching usando 'Cache-control: public, no-cache;' nella tua intestazione HTTP ('no-cache' in realtà non significa nessun caching, i nomi sono un po 'spenti). – Imagist

+3

È ancora possibile memorizzare nella cache * e * il browser chiamare il server. Si chiama convalida della cache. Lo fai inviando 'Cache-control: private, must-revalidate' (privato poiché non dovrebbe essere condiviso tra utenti) e l'header' Last-Modified' o 'ETag'. Quindi, quando il browser invia 'If-Modified-Since' o' If-None-Match' risponde con lo stato '304' se non è cambiato nulla da quando l'immagine è stata generata. – Kornel

48

Prima di tutto, se si sta utilizzando le sessioni, è necessario disattivare session_cache_limiter (impostandolo su none o public). Le intestazioni che invia sono piuttosto negative per le cache.

session_cache_limiter('none'); 

quindi inviare Cache-Control: max-age=number_of_seconds ed eventualmente un equivalente Expires: intestazione.

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

Per la migliore cacheability, inviare Last-Modified intestazione e rispondere con stato 304 e il corpo vuoto se il browser invia una corrispondenza If-Modified-Since intestazione.

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

Per brevità sto barare qui un po '(l'esempio non verifica la data), ma è valido fino a quando non ti dispiace browser mantenendo il file memorizzato nella cache per sempre:

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

Sì, sto usando 'sessioni'. Hm, sembra che tu dica sia quello di cui ho bisogno, ma non capisco come ottenerlo insieme al codice funzionante. Come scrivo se voglio che il browser memorizzi l'immagine per un anno? – Johan

+0

Grazie mille, il suo wokring perfetto per me è così bello! grazie grazie grazie! :) – ParisNakitaKejser

+0

Il bit '' If-Modified-Since'' è il "d'oh" o "eureka!" momento, quale preferisci! – Agamemnus

3

è possibile memorizzare le immagini generate in una directory chiamata "ShowImage" in modo che si sarebbe inserirli come questo

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

Poi si inserisce un file .htaccess nella stessa directory che chiamerà showImage.php? id = nel caso in cui il file non esiste, ad esempio:

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

Basta leggere nel vostro commento che si vuole fare il caching lato client: è sufficiente impostare le intestazioni HTTP cache-correlata in base a http://www.mnot.net/cache_docs/


si prega di essere consapevole del fatto che la query è vulnerabile a iniezioni SQL, perché non si disinfettare/sfuggire $ _GET [ 'id']: http://php.net/mysql_real_escape_string

0

Si prega di non indirizzare le immagini sono una risorsa id identica. utilizzare gli URL assoluti per le immagini, preferibilmente in un sottodominio, preferibilmente meno cookie. Il browser eseguirà la memorizzazione nella cache delle immagini. Un trucco perfetto per caricare le immagini più velocemente sui siti Web è metterlo su un CDN o altro sito. Questo perché i browser limitano il numero di thread di richieste parallele a un dominio.

Un altro modo pulito di lavorare con le immagini è sputare, cercare. Salva molta larghezza di banda e anche richieste.

È anche possibile utilizzare il caricamento diretto di bitmap se la velocità è così importante.Questo non è consigliato per le immagini di grandi dimensioni però. Se le sue icone e le piccole immagini/gif che stai caricando. Puoi usare bitmap direttamente sulla pagina.

7

Ecco po 'di codice che uso per il supporto 304 intestazione:

/** 
    * @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; 
    } 
Problemi correlati