November 19th, 2008 Category: Zend Framework
11 Comments »








El concepto de cachear contenido es simple. Cada vez que generamos una pagina con contenido dinamicamente con PHP, lo que hacemos desde el lado del servidor es procesar los .php, estos generalmente tienen cierta logica, para generar el contenido que vamos a mostrar, como buscar en la base datos, llamar algun webservice, y depende el sistema mas o menos cosas. Con Zend_Cache nos evitamos de estos pasos.

Lo que hacemos con Zend_Cache, es generar el html(xml, json, etc) final, y almacenarlo en el file system. De esta manera cada vez que hagamos llamen a nuestra web vamos a llamar a nuestro html final, y no volver a generar el html que generamos en peticiones anteriores. Esto sirve para web donde el contenido no cambia constantemente.

Por ejemplo si tuvieramos un diario, como www.clarin.com.ar donde acceden millones de personas mensualmente, pero sabemos que el unico momento donde se cambia la portada es cuando aparece una nueva nota, aunque las paginas internas siguen siendo las mismas.

Para este caso es ideal algo como Zend_Cache, podemos Cachear toda portada, y cada una de las paginas internas, si desde la administracion se carga una nueva nota, se borra el cache anterior y se genera uno nuevo muy facilmente.

Pero hasta ahora solo vimos la teoria.

Manos a la obra

Lo primero que tenemos que hacer antes de cachear nuestras paginas es configurar como queremos que funcione Zend_Cache. En este ejemplo le vamos a dar un tiempo de vida determinado, vamos a indicarle donde queremos que almacene las paginas cacheadas, y vamos a decirle que actions y vistas queremos que cachee. Este codigo podemos ponerlo en nuestro bootstrap.

 7200,
   'debug_header' => true, // for debugging
   'regexps' => array(
       // cache the whole IndexController
       '^/$' => array('cache' => true),

       // cache the whole IndexController
       '^/index' => array('cache' => true),

       '^/home' => array('cache' => true),
       // we don't cache the ArticleController...

       // we don't cache the ArticleController...
       '^/news' => array('cache' => true),

       // we don't cache the ArticleController...

       // ... but we cache the "view" action of this ArticleController
       '^/news/list/view' => array(
           'cache' => true
       )
   ),
   'default_options' => array(
   		   'make_id_with_post_variables' => true,
           'make_id_with_cookie_variables' => true,
           'cache_with_cookie_variables' => true
    )

);

$backendOptions = array(
    'cache_dir' => '/tmp/zend_cache'
);

// getting a Zend_Cache_Frontend_Page object
$cache = Zend_Cache::factory('Page',
                             'File',
                             $frontendOptions,
                             $backendOptions);
$cache->start();
?>

En este ejemplo estamos cacheando los controller news, home, index. Ademas le indicamos que el directorio para los files es /tmp/zend_cache (hay que crearlo!!)

Los tiempos que se reducen dependen de la cantidad de datos que busquemos en la base de datos, webservice, o que dependa de cierta logica.

Para un blog, o un portal con muchos hits diarios esto es indispensable al menos que tengamos hardware de sobra. En este blog yo uso WP-Cache de Ricardo Galli que hace lo mismo que Zend_Cache.


Invitame una Cerverza


Comentar


11 Responses


Gabriel 2009-01-17 10:18:01
Hola pablo, como estas? vi este articulo en tu blog, he intente implementarlo en mi sitio, pero no lo puedo hacer andar. Te comento como lo tengo:
Primero he configurado con un router en el bootstrap, que cuando se acceda por url por ejemplo a buscar/cualquiercosa.htm, este envíe esa palabra cualquiercosa en una variable a un controlador el cual una accion buscara esa palabra en la base de datos, y los devolvera tabulando los datos en su correspondiente view (archivo.phtml).

Ahora bien, el problema es que quiero cachear todas las paginas que va a ir componiendo la accion del controler, pero no puedo configurarlo. Lo he intentado muchas veces pero no logro darme cuenta en que estoy fallando. Lo ultimo que probé fue algo como lo siguiente:

[PHP]
public function indexAction() {
$frontendOptions = array(
'lifetime' => 7200,
'debug_header' => true, // for debugging );

$backendOptions = array(
'cache_dir' => '/tmp/');

// getting a Zend_Cache_Frontend_Page object
$cache = Zend_Cache::factory('Page',
'File',
$frontendOptions,
$backendOptions);

$cache->start();

$f = new Zend_Filter_StripTags ( );
/* Busco la palabra en la base de datos y devuelvo los resultados */
$urlPagina = $f->filter ( $this->_request->getParam ( 'busqueda' ) );
$pagina = new ContenidoPaginas ( );
$datosPagina = $pagina->getPagina ($urlPagina);
/* Muestro el resultado en la vista */
$this->view->contenido = $datosPagina ['contenido'];

}
[/PHP]

La verdad que esto no graba nada en mi carpeta temporal.
La verdad he intentada varias cosas y no logro hacerlo andar.
Podrias ayudarme ?

Desde ya, muchisimas gracias. Con tu blog he aprendido cosas que no las he encontrado en otro lugar, y con muy buena onda de parte tuya!!

Gabriel 2009-01-17 13:04:59
Hola devuelta, puse el mismo codigo en el booststap, y no hace nada, supongo que sera el tema de las ruta en donde le digo que quiero cachear. Para hacerlo mas facil, estoy tratando de hacerlo andar en una estructura de directorio basi. La estructura es como la siguiente:
-Html
--index.php (aca esta el bootstrap)
-Aplication
--default
---controllers
----index

alguna idea?

Pablo Morales 2009-01-19 10:42:11
Acordate que esa carpeta donde vas a guardar las paginas tiene que tener permisos de escritura.

Decime cual es el error que te tira.

Pablo Morales 2009-01-19 16:31:12
Fijate en estos articulos

http://blog.astrumfutura.com/archives/380-Zend-Framework-Page-Caching-Part-1-Building-A-Better-Page-Cache.html

http://blog.astrumfutura.com/archives/381-Zend-Framework-Page-Caching-Part-2-Controller-Based-Cache-Management.html

Gabriel 2009-01-19 17:50:39
Gracias Pablo por responder, voy a pegarle una mirada. No me mostraba ningun error, y lac arpeta tmp tenia permisos de escritura. Calculo que debe ser por la configuracion de la ruta de los controladores. Igual resolví aplicando el otro método de cacheo, el cual cachea las variables. (ese me resulto mas util).

Un abrazo.

Pablo López 2011-07-14 16:03:19
Hola, estoy usando el cache de zend (full page cache) y necesito limpiar el cache una vez que el usuario se loguea/desloguea, debido a que sino queda una porcion de la pagina con datos erroneos (de cuando estaba logueado o no).

Como puedo hacer para eliminar el cache, pero solamente el que es dependiente del id de la sesion?
por que si hago un $cache->clean() me borra todo el cache, y no el que es para el usuaroi

Pablo Morales 2011-07-14 16:33:43
Lo que deberias hacer es si esta logueado no preguntar si existe una version de l apagina en cache, y cargar los datos como si no existiera

Pablo López 2011-07-14 16:35:27
mmm pero en ese caso para que me sirve el cache? no puedo o 1- cachear ambas versiones (logeado o no logueado) o 2- excluir una seccion del cache?

Pablo Morales 2011-07-14 16:39:42
podes cachear las dos versiones si queres.

cambia el id ponele


$cacheId = 'esteesmiid';

if( $this->auth->isLogged() ){
$cacheId .= 'logged';
}


Y eso seria suficiente

Pablo López 2011-07-14 16:42:02
buenisimo! voy a probar eso, muchas gracias