CakePHP: Usar caché en el modelo

Podemos aprovecharnos del sistema de caché que viene por defecto en CakePHP, pensado sobre todo para las vistas, para almacenar de forma estática en un fichero información obtenida desde el modelo para tratar de minimizar los accesos a Base de Datos.

Trataré de explicarme mediante un ejemplo.

Pongamos un modelo News que tiene un método getLastNews que obtiene las últimas noticias creadas:


class News extends AppModel {
    var $name = 'News';

    function getLastNews(){
        $find_params = array('limit' => 5, 'order' => 'News.id DESC');
        $this->find('all', $find_params);
    }
}

El código anterior obtendría las últimas 5 noticias y cada vez que se llame a este método se genera una consulta a la Base de Datos.

Ahora haremos unas modificaciones para generar un caché con estas últimas 5 noticias:


class News extends AppModel {

    var $name = 'News';

    function getLastNews(){
        $data = $this->_getCache('ultimas-noticias');
        if ( empty( $data ) ){
            $find_params = array('limit' => 5, 'order' => 'News.id DESC');
            $data = $this->find('all', $find_params);
            $this->_toCache('ultimas-noticias', $data);
        }
        return $data;
    }

    function _toCache($cache_file_name = null, $data = null) {
        if(! $cache_file_name) return false;
        if(! $data) return false;

        Cache::config(null, array('engine' => 'File', 'path'=> CACHE . '/data/'));
        Cache::write($cache_file_name, $data, array('duration' => 7200, 'config' => null));

        return true;
    }

    function _getCache($cache_file_name = null){
        $data = null;
        if(! $cache_file_name) return $data;

        Cache::config(null, array('engine' => 'File', 'path' => CACHE . '/data/');
        $data = Cache::read($cache_file_name);

        return($data);
    }

}

El código es mejorable, como poner los métodos de acceso a caché en el app_model, pero éste nos sirve para ver de un vistazo el funcionamiento del caché.
Ahora el método getLastNews, para obtener la información comprueba si existe en el caché, usándolo si existe y en caso contrario, consultando a la Base de Datos y creándolo para el futuro.

Para profundizar en el concepto del caché, su uso y configuración lo mejor es darse una vuelta por la documentación oficial.

Esta “técnica” se complementa muy bien con la reescritura de la callback find.

Tags: ,

2 Responses to “CakePHP: Usar caché en el modelo”

  1. ala_747 Says:
    October 15th, 2009 at 2:46 pm

    ¡Es una gran idea!

    Justamente ayer estaba jugueteando un poco con, te diría, el mismo concepto pero en WordPress.

    WP tiene su propio sistema de “Object Cache”, aunque su uso no está muy extendido que digamos (¡y lo bien que le vendría a más de uno y más de dos plugins y themes!)… a pesar de que sus beneficios son, cuando menos, interesantes.

    La documentación oficial está en http://codex.wordpress.org/Function_Reference/WP_Cache (aunque le faltan un par de vueltas y un poco de alegría).

    Aquí te dejo el mismo método de tu ejemplo pero en “sintaxis WP” para que veas lo parecidos que se quedan :)


    function getLastNews() {
    if ( !$data = wp_cache_get( 'ultimas_noticias', 'news_collections' ) ) {
    $data = get_posts( 'numberposts=5' );
    wp_cache_add( 'ultimas_noticias', $data, 'news_collections', 7200 );
    }
    return $data;
    }

    ¡Ah! Cabe aclarar que el “Object Cache” de WP dejó de ser “persistente” más o menos por la v2.6 y devino en un cache de memoria… esto significa que no tira de archivos físicos para guardar la data. De todas formas, siempre se pueden usar trucos muy simples para hacer que lo baje a disco si hiciera falta (lo más facil siempre será pisando el sistema con un archivo “object-cache.php” que defina lo que nos haga falta puesto en el lugar adecuado). Según mis pruebas de ayer, el bicho en memoria funciona… y bastaaaante bien.

    Ya sabes que CakePHP sigue siendo una cuenta pendiente para mí, pero es bueno saber que tiene herramientas que ya estoy acostumbrado a usar por otros lados ;)

    ¡Gracias por el tip!

    Abz!

  2. faemino Says:
    October 15th, 2009 at 10:59 pm

    Gracias por la información aportada. Siempre te tengo ahí cuando requiero algo de WP avanzado ;-)

Leave a Reply