Manejo del encabezado If-modified-since en un PHP-script

Tengo un script PHP que se llama con un parámetro ? Img = .

El valor para ese parámetro es una URL (urlencoded) de una imagen.

Mi script comprueba si esa imagen ya está almacenada en mi servidor.

Si no, lo descarga. Después de eso, opcionalmente, cambia el tamaño de la imagen y la envía a STDOUT, es decir, de vuelta al navegador solicitante, junto con los encabezados Content-Type y 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 

Esto es necesario para solucionar algunos problemas de Flash / crossdomain.xml y funciona bien para mí desde hace más de un año:

enter image description here

Sin embargo, me gustaría agregar funcionalidad para manejar el encabezado If-Modified-since entrante, para enviar una respuesta 304 no modificada .

Mis preguntas son:

1) ¿Es eso posible en PHP, cuando se ejecuta en Apache?

2) ¿Cómo manejar (es decir, analizar y producir) las mejores fechas en PHP aquí?

Pregunta adicional) ¿Cómo agregar un encabezado Content-Length para las imágenes redimensionadas?

Mi código está debajo (he omitido la parte de descarga de 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  

No le pido a nadie que haga mi trabajo, simplemente solicite algunos buenos punteros o fragmentos de código, ya que todavía no tengo experiencia en esas áreas (encabezados + fechas) de PHP.

¡Esto definitivamente es posible en PHP!

Cuando el navegador comprueba si hubo modificaciones, envía un encabezado If-Modified-Since ; en PHP, este valor se establecería en $_SERVER['HTTP_IF_MODIFIED_SINCE'] .

Para decodificar el valor de fecha / hora (codificado usando rfc822, creo), puede usar strtotime() , entonces:

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

Explicación: si el encabezado If-Modified-Since es enviado por el navegador Y la fecha / hora es al menos la fecha de modificación del archivo que está publicando, escriba el encabezado “304 Not Modified” y deténgalo.

De lo contrario, la secuencia de comandos continúa como de costumbre.

Recientemente tuve que usar esta característica (que sirve imágenes a través de PHP) para hacer que las imágenes sean visibles solo para usuarios registrados. El código de Jack fue útil, pero tuve que hacer algunos cortes para que funcionara perfectamente. Pensé que debería compartir esto.

 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); } 

En resumen, la secuencia de comandos devuelve No modificado si se trata de una solicitud de navegador HTTP_IF_MODIFIED_SINCE . De lo contrario, la imagen se publica con los encabezados y fechas de caducidad correspondientes.