TigerZF
🌐Español

Capítulo 17. Zend_Cache

17.1. Introducción

Zend_Cache proporciona una forma genérica de almacenar en caché cualquier dato.

El almacenamiento en caché en Zend Framework es gestionado por frontends mientras que los registros de la caché se almacenan a través de adaptadores backend (File, Sqlite, Memcache...) a través de un sistema flexible de IDs y etiquetas. Usando estos, es fácil eliminar tipos específicos de registros posteriormente (por ejemplo: "eliminar todos los registros de la caché marcados con una etiqueta dada").

El núcleo del módulo (Zend_Cache_Core) es genérico, flexible y configurable. Aun así, para sus necesidades específicas existen frontends de caché que extienden Zend_Cache_Core por conveniencia: Output, File, Function y Class.

Ejemplo 17.1. Obtener un frontend con Zend_Cache::factory()

Zend_Cache::factory() instancia los objetos correctos y los enlaza entre sí. En este primer ejemplo, usaremos el frontend Core junto con el backend File.

$frontendOptions = array(
   'lifetime' => 7200, // cache lifetime of 2 hours
   'automatic_serialization' => true
);

$backendOptions = array(
    'cache_dir' => './tmp/' // Directory where to put the cache files
);

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

[Note] Frontends y backends compuestos por varias palabras

Algunos frontends y backends se nombran usando varias palabras, como 'ZendPlatform'. Al especificarlos en la fábrica, sepárelos usando un separador de palabras, como un espacio (' '), un guion ('-'), o un punto ('.').

Ejemplo 17.2. Almacenar en caché el resultado de una consulta a la base de datos

Ahora que tenemos un frontend, podemos almacenar en caché cualquier tipo de dato (activamos la serialización). Por ejemplo, podemos almacenar en caché el resultado de una consulta a la base de datos muy costosa. Después de que se almacena en caché, ni siquiera es necesario conectarse a la base de datos; los registros se obtienen de la caché y se deserializan.

// $cache initialized in previous example

// see if a cache already exists:
if( ($result = $cache->load('myresult')) === false ) {

    // cache miss; connect to the database

    $db = Zend_Db::factory( [...] );

    $result = $db->fetchAll('SELECT * FROM huge_table');

    $cache->save($result, 'myresult');

} else {

    // cache hit! shout so that we know
    echo "This one is from cache!\n\n";

}

print_r($result);

Ejemplo 17.3. Almacenar en caché la salida con el frontend Output de Zend_Cache

'Marcamos' las secciones en las que queremos almacenar en caché la salida añadiendo alguna lógica condicional, encapsulando la sección entre los métodos start() y end() (esto se parece al primer ejemplo y es la estrategia central para el almacenamiento en caché).

Dentro, escriba sus datos como de costumbre - toda la salida se almacenará en caché cuando la ejecución llegue al método end(). En la siguiente ejecución, toda la sección se omitirá en favor de obtener los datos de la caché (siempre que el registro de caché sea válido).

$frontendOptions = array(
   'lifetime' => 30,                   // cache lifetime of 30 seconds
   'automatic_serialization' => false  // this is the default anyways
);

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

$cache = Zend_Cache::factory('Output',
                             'File',
                             $frontendOptions,
                             $backendOptions);

// we pass a unique identifier to the start() method
if(!$cache->start('mypage')) {
    // output as usual:

    echo 'Hello world! ';
    echo 'This is cached ('.time().') ';

    $cache->end(); // the output is saved and sent to the browser
}

echo 'This is never cached ('.time().').';

Observe que mostramos el resultado de time() dos veces; esto es algo dinámico con fines demostrativos. Intente ejecutar esto y luego actualizar la página varias veces; notará que el primer número no cambia mientras que el segundo cambia a medida que pasa el tiempo. Esto se debe a que el primer número se generó en la sección en caché y se guardó junto con otra salida. Después de medio minuto (hemos configurado el tiempo de vida en 30 segundos), los números deberían coincidir de nuevo porque el registro de caché ha expirado -- solo para volver a almacenarse en caché. Debería probar esto en su navegador o consola.


[Note] Nota

Al usar Zend_Cache, preste atención al importante identificador de caché (pasado a save() y start()). Debe ser único para cada recurso que almacene en caché, de lo contrario los registros de caché no relacionados podrían anularse mutuamente o, incluso peor, mostrarse en lugar de otro.