borrame.com - Colección particular de recortes de código y documentación para programación web

Canales RSS

Lo más fresco

  1. Bookmarklets Nuevo
  2. Recetario básico para CakePHP/2 Nuevo
  3. Certificado auto-firmado Nuevo

Sugerencias del chef

Lo más visitado

  1. Fecha y hora
  2. Dar formato a un número
  3. Reiniciar secuencia
  4. Vaciar un esquema
  5. Certificado auto-firmado
Compartir esta página

Caché del navegador

Guardar en caché

A menudo se emplea PHP simplemente para añadir menús, encabezados o pies de página usando el tradicional include(). Un efecto secundario es que al tratarse de un script en PHP la página ya no se guarda en la caché del navegador y se descarga desde Internet cada vez que se visualiza; sieeeempre la misma página porque nada cambia en ella de una vez a otra.

Con esta función, llamada al principio de nuestro script, le indicamos al navegador la fecha real de la última modificación y cuánto tiempo debe conservar la página en caché.

/** * Genera los encabezados necesarios para indicar que el documento se guarde o no en caché * * @param bool $activar Genera encabezados para guardar en caché (true) o para no cachear (false) * @param int $horas Tiempo que el navegador debe conservar la página en caché * @param bool $if_modified_since Indica si respetar el encabezado If-Modified-Since * Si $if_modified_since es TRUE, cuando la página no se ha modificado desde la fecha indicada en * If-Modified-Since se genera un código de estado HTTP 304 y se detiene la ejecución del script * * Nota: esta función utiliza la fecha de modificación de la _página actual_ como referencia. Esta * fecha no tiene en cuenta otros archivos (como bloques situados en includes) o contenidos dinámicos * por lo que sólo es una medida fiable en páginas estáticas o pseudo-estáticas. Esto es un problema * si se utiliza $if_modified_since=TRUE en páginas dinámicas ya que el navedor podría conservar una * versión obsoleta mucho más allá de lo establecido en $horas * * @version v2011-02-11 */ function cache($activar, $horas=3, $if_modified_since=FALSE){     // Obecedemos If-Modified-Since si queremos usar caché     if( $activar && $if_modified_since && isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ){         $fecha_cache = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);         if( $fecha_cache!==FALSE && $fecha_cache>=getlastmod() ){             header('Last-Modified: ' . gmdate('D, d M Y H:i:s', getlastmod()) . ' GMT', TRUE, 304);             exit;         }     }     header('Last-Modified: ' . gmdate('D, d M Y H:i:s', getlastmod()) . ' GMT');     if($activar){         // Guardar en caché         header('Expires: ' . gmdate('D, d M Y H:i:s', time()+60*60*$horas) . ' GMT');         header('Cache-Control: max-age=' . 60*60*$horas . ', s-maxage=' . 60*60*$horas . ', must-revalidate, proxy-revalidate');         session_cache_limiter(FALSE); // Deshabilitamos los encabezados de caché de session_start()         if( session_id() ){             // Una sesión ya iniciada ha generado un encabezado Pragma: no-cache             if( function_exists('header_remove') ){                 header_remove('Pragma');             }else{                 header('Pragma:');             }         }     }else{         // No guardar en caché         header('Expires: ' . gmdate('D, d M Y H:i:s', time()-86400*365*10) . ' GMT');         header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');         header('Pragma: no-cache');     } }

Nótese que esto no nos impide recargar la página con el botón de actualizar y, en cambio, hace mucho más ágil navegar por el sitio.

No guardar en caché

Si no queremos reutilizar la página de la caché podemos llamar a la función con $activar=FALSE. O podemos simplemente no llamarla: ésa acostumbra a ser configuración predeterminada de PHP.

Notas

Acerca de If-Modified-Since

Este encabezado HTTP, enviado por el navegador, permite mantener una conversación tal que así:

Al contrario que con el sistema «ten esto tres horitas en caché y luego me lo vuelves a pedir», el navegador conservará la versión que tenga hasta que le digamos que la página ha cambiado. Y si la página cambia sin que nos demos cuenta esto pueden ser semanas o meses. Para que el sistema sea funcional necesitamos bien que la página sea estática (en cuyo caso getlastmod() nos da la información correcta) bien indicar a mano la fecha de modificación (sería fácil retocar la función para alimentarla con una fecha sacada de, por ejemplo, la base de datos). Si no se está seguro es mejor dejar $if_modified_since=FALSE.

Historial

v2011-02-11
Documentar mejor los parámetros y cambiar el valor predeterminado de $if_modified_since.
v2010-08-23
Implementar la respuesta al encabezado If-Modified-Since.
La caché no se activaba en páginas con sesiones si la sesión había sido iniciada con anterioridad.
Generar el encabezado Last-Modified también al desactivar la caché.
v2009-05-08
Agrupado el código en una función y actualizadas las explicaciones.
La caché no se activaba en páginas con sesiones.
v2005-08-25
Primera versión.

Esta página ha sido impresa el sábado 23 de septiembre de 2017 (02:22:11 +0200) desde http://borrame.com/recortes/php/cache-navegador.html. La última vez que miré contenía HTML válido con CSS fresquito y si tiene flatas de ortografía ha sido sin querer.

borrame.com es el sitio anteriormente conocido como bits.demogracia.com (no confundir con Demogracia, que sólo pasaba por ahí).

© 2005-2017 by Álvaro González (alvaro.es) • Burgos (España) • borrame.com