Gestire l'intestazione If-modified-since in uno script PHP

Ho uno script PHP che viene chiamato con un parametro ? Img = .

Il valore per quel parametro è un URL (urlencoded) di un'image.

Il mio script controlla, se quell'image è già memorizzata sul mio server.

In caso contrario, lo scarica. Dopodiché, ridimensiona facoltativamente l'image e la invia a STDOUT, cioè al browser richiedente, anteposto alle intestazioni Content-Type e Last-modified :

Connection:close Content-Type:image/jpeg Date:Fri, 01 Jun 2012 08:28:30 GMT Last-Modified:Fri, 01 Jun 2012 08:02:44 GMT Server:Apache/2.2.15 (CentOS) Transfer-Encoding:chunked X-Powered-By:PHP/5.3.3 

Questo è necessario per risolvere alcuni problemi di Flash / crossdomain.xml e funziona bene per me da oltre un anno:

    inserisci la descrizione dell'immagine qui

    Tuttavia mi piacerebbe aggiungere funzionalità per gestire l'intestazione If-Modified-since in ingresso – per submit una risposta 304 non modificata .

    Le mie domande sono:

    1) È ansible anche in PHP, se eseguito in Apache?

    2) Come gestire (es. Analizzare e produrre) le date migliori in PHP qui?

    Domanda bonus) Come aggiungere un'intestazione Content-Length per le immagini ridimensionate?

    Il mio codice è di sotto (ho omesso la parte di scaricamento CURL):

     <?php define('CACHE_DIR', '/var/www/cached_avatars/'); $img = urldecode($_GET['img']); $cached = CACHE_DIR . md5($img); # omitted downloading part for brevity $readfh = fopen($cached, 'rb'); if ($readfh) { flock($readfh, LOCK_SH); $size = getimagesize($cached); $w = $size[0]; $h = $size[1]; $type = $size[2]; $mime = $size['mime']; # find the downscale factor to fit image into $maxw x $maxh $scale = max($w / $maxw, $h / $maxh); header('Content-Type: ' . $size['mime']); header('Last-Modified: ' . gmdate('D, d MYH:i:s T', filemtime($cached))); $length = filesize($cached); $buf = fread($readfh, $length); fclose($readfh); # the image is smaller than $maxw x $maxh, do not scale up if ($scale <= 1) { header('Content-Length: ' . $length); print($buf); return; } $tw = $w / $scale; $th = $h / $scale; $image = imagecreatefromstring($buf); $thumb = imagecreatetruecolor($tw, $th); imagecopyresampled($thumb, $image, 0, 0, 0, 0, $tw, $th, $w, $h); imagedestroy($image); # How to add Content-Length here, after image resizing? if (IMAGETYPE_JPEG == $type) imagejpeg($thumb, null, 75); else if (IMAGETYPE_PNG == $type) imagepng($thumb, null, 9); else if (IMAGETYPE_GIF == $type) imagegif($thumb, null); imagedestroy($thumb); } ?> 

    Non sto chiedendo a nessuno di fare il mio lavoro per me, solo chiedendo dei buoni suggerimenti o frammenti di codice – perché non ho ancora esperienza in quelle aree (intestazioni + date) di PHP.

    Questo è sicuramente ansible in PHP!

    Quando il browser controlla se ci sono state modifiche, invia un'intestazione If-Modified-Since ; in PHP questo valore verrebbe impostato in $_SERVER['HTTP_IF_MODIFIED_SINCE'] .

    Per decodificare il valore di data / ora (codificato usando rfc822 credo), puoi semplicemente usare strtotime() , quindi:

     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($localFileName)) { header('HTTP/1.0 304 Not Modified'); exit; } 

    Spiegazione: se l'intestazione If-Modified-Since viene inviata dal browser E la data / ora è alless la data di modifica del file che stai servendo, scrivi l'intestazione "304 Not Modified" e interrompi.

    Altrimenti, lo script continua normalmente.

    Recentemente ho dovuto utilizzare questa function (che serve l'image tramite PHP) per rendere le immagini visibili solo per gli utenti registrati. Il codice di Jack è stato utile, ma ho dovuto fare alcuni hack per farlo funzionare perfettamente. Ho pensato di condividere questo.

     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($path_to_image)) { header('HTTP/1.0 304 Not Modified'); header("Cache-Control: max-age=12096000, public"); header("Expires: Sat, 26 Jul 2015 05:00:00 GMT"); header("Pragma: cache"); exit; }else{ header("Content-type: image/jpeg"); header("Cache-Control: max-age=12096000, public"); header("Expires: Sat, 26 Jul 2015 05:00:00 GMT"); header("Pragma: cache"); echo file_get_contents($path_to_image); } 

    In breve, lo script restituisce Not Modified se si tratta di una richiesta del browser HTTP_IF_MODIFIED_SINCE . Altrimenti, l'image viene pubblicata con intestazioni appropriate e date di scadenza.