« »
May 16

El motor de PHP es uno de los más rápidos generando páginas web aún así nunca será tan rápido como no tener que generar nada y que el servidor web devuelva páginas estáticas. A pesar de disponer de una aplicación web escrita en PHP podemos conseguir la misma velocidad que en una web estática cacheando las páginas generadas. Lo que se porpone a continuación es un sistema de cache donde las páginas sólo se generarán la primera vez que se acceda a ellas, en siguientes peticiones el servidor web devolverá las páginas estáticas generadas.

Existen varias propuestas de sistemas de cache donde siempre se ejecuta un script PHP trabajando con el output-buffer para guardar la respuesta. Estos sistemas de cache tiene el inconveniente de que a pesar de tener la página cacheada siempre estamos ejecutando un script PHP con el coste en rendimiento que ello conlleva. Como solución se propone trabajar con el output-buffer pero usar la directiva de configuración ErrorDocument del Apache para que si ya tenemos la página generada no se ejecute ni un script PHP.

La directiva ErrorDocument se usa para configurar lo que el servidor devolverá al cliente en caso de error. Pues bien, se trata de configurar el error que indica que no existe la página solicitada (error 404) para que apunte a un script PHP donde generaremos la página. En la siguiente petición a la misma página el Apache devolverá directamente el archivo HTML generado.

Algunas consideraciones previas:

  • Necesitas tener permisos de escritura en el directorio donde pretendas guardar las páginas. (esto lo puedes conseguir fijando los permisos a 777).
  • Necesitas poder configurar la directiva ErrorDocument de tu servidor Apache. (algunos hostings no lo permiten).

[1] Configurar el Apache

Debemos añadir lo siguiente en nuestro .htaccess o en la configuración del servidor Apache:

ErrorDocument 404 genera_pagina.php

[2] Añadir el código necesario

Es necesario añadir un bloque de código al principio y al fin de cada script. A continuación una implementación de ejemplo:

[php] //obtenemos el nombre de la página solicitada
$pagina = array_pop(explode(‘/’,$_SERVER[‘REQUEST_URI’]));
//iniciamos el output buffer
ob_start();
//………………………..
//código que genera la página
echo ‘hola’;
//………………………..
//obtenemos el output bufer
$contenido = ob_get_contents();
//guardamos la pagina estática
file_put_contents($pagina,$contenido);
//volcamos por pantalla y cerramos el output buffer
ob_end_flush(); [/php]

Se puede guardar el anterior código en un script llamado “genera_pagina.php” sustituyendo la linea echo “hola” por el código de nuestra aplicación (p.e. con un include()) o podemos dividir el código en dos scripts y usar las directivas auto-append-file y auto-prepend-file para no tener que modificar nuestra aplicación (cortar por las lineas de puntos).

En el ejemplo se obtiene sólo el nombre de la página solicitada y se crea una archivo con el mismo nombre con el contenido de la respuesta. Pero no soporta directorios, está pensado para trabajar sobre un directorio en concreto o en una web sin directorios en las URL. Cambiando la primera linea del ejemplo podéis hacer que se comporte de otra forma, el ejemplo simplemente obtiene el último trozo de la URL usando como delimitador “/”.

A diferencia de otras propuestas de cache aquí estamos modificando el Apache para que ejecute un script en caso de no encontrar una página. Es por esto que en vuestra aplicación debéis generar una página de error en el caso de que la página solicitada no exista. Lo correcto es que en esta página de error se envíe la header correspondiente tal y como lo haría el Apache por defecto:

[php] header(“HTTP/1.0 404 Not Found”); [/php]

[3] Mantenimiento de la cache

Por ultimo nos falta programar un proceso en el cron para que elimine los archivos de la cache que han caducado. Por ejemplo para mantener una cache de una hora:

0 * * * * find /web -mtime +1h -print0 | xargs -0 rm -f

Se ha de sustituir “/web” por la ruta física donde tenemos nuestra aplicación web. Si no queremos programar un cron siempre podemos hacer lo anterior desde algún script PHP que se ejecute constantemente en nuestra web.

Lo que comento en este post no es nada nuevo, ya fue propuesto por Rasmus Lerdorf en el PHPCon del 2002 (aunque un poco caducada la presentación que enlazo merece la pena).

Be Sociable, Share!
Tagged with:

8 Responses to “Cache de páginas estáticas para PHP”

  1. meneame.net says:

    Cache de páginas estáticas para PHP…

    El motor de PHP es uno de los más rápidos generando páginas web aún así nunca será tan rápido como no tener que generar nada y que el servidor web devuelva páginas estáticas. En este artículo se presenta un sistema de cache que a diferencia d…

  2. Cache de páginas estáticas para PHP…

    El motor de PHP es uno de los más rápidos generando páginas web aún así nunca será tan rápido como no tener que generar nada y que el servidor web devuelva páginas estáticas. A pesar de disponer de una aplicación web escrita en PHP podemos co…

  3. Cesar Rodas says:

    Ofrezco una clase que habia hecho con un objetivo similar. Puedes hecharle una miradita http://cesarodas.com/2007/06/gcache_helping_php_to_work_faster.html

    La clases es Public Domain

  4. Miguel Oseguera says:

    Excelente aporte Muchisismas Gracias me ahorraste un tabajote

  5. El problema de hacerlo con ErrorDocument 404 es que el log de apache ya no te sirve, todos los hits de página generan un error. Para ello es mejor usar mod_rewrite, tipo lo que usa wordpress. Y no es recomendable usar auto-append-file y auto-prepend-file, pq después se ejecutan en TODOS los scripts php de tu site, y estoy seguro que sólo algunos scripts serian para cachear.

  6. Oriol says:

    Jep,

    El problema de hacerlo con ErrorDocument 404 es que el log de apache ya no te sirve, todos los hits de página generan un error.

    Si tienes activado el log de Apache se logearán como error los accesos a las páginas que no tengas generadas, pero NO todos los accesos.

    Para ello es mejor usar mod_rewrite, tipo lo que usa wordpress.

    Si usas una solución basada en mod_rewrite ob_start es necesario ejecutar un script PHP en cada acceso. Precisamente lo que propone el post es un sistema para no tener que hacer esto.

    no es recomendable usar auto-append-file y auto-prepend-file, pq después se ejecutan en TODOS los scripts php de tu site.

    Este es precisamente el objetivo de estas directivas. Decir que es o no recomendable es muy subjetivo, depende de tus necesidades. En el ejemplo descrito se supone que muchos de los accesos irán a las páginas .html directamente. En todo caso puedes configurar Apache para sólo usar las directivas en unos determinados directorios.

  7. Oriol, entendí que pasabas TODAS las peticiones al ErrorDocument 404, todos mis argumentos (erronios) se basaban en esta premisa.
    Lo del auto-append-file y auto-prepend-file, creo que es la pero forma de hacer-lo, no todos los ficheros .php tendran que cachearse.

    Sugerencia: Podrías permitir que los comentaristas se suscribieran a los comentarios a fin de ver las posibles réplicas. No me havia enterado que lo hubieras contestado.

Leave a Reply

preload preload preload