PHP Caching com Zend_Cache

O Zend_Cache é um componete distribuído junto com o Zend Framework. Pode ser usado tanto como um módulo standalone ou junto com o framework. Muito flexível, permite que você decida o que quer fazer cache (frontend) e onde armazenar (backend). Ao configurar uma instância do Zend_Cache você deve informar dois grupos de opções. Um para o frontend e outro para o banckend. Existem vários frontends e backends disponíveis por padrão no Zend Framework. Todos frontends extendem a classe Zend_Cache_Core que provê funcionalidades genéricas de cache.

Tipos de frontends disponíveis

Além da possibilidade de usar o frontend Core que provê cache de dados de forma básica, o Zend_Cache permite vários outros tipos de cache de dados.

  • Class – Permite realizar o cache de objetos e de chamadas para métodos estáticos.
  • File – Realiza o cache de arquivos que são carregados para dentro do PHP.
  • Function – Realiza o cache do retorno de uma função.
  • Output – Utiliza o Output Buffering do PHP. Ideal para fazer cache parcial de uma página. Realizará o cache de tudo que estiver entre os métodos start() e end().
  • Page – Semelhante ao frontend de Output. Porém com o Page o cache é realizado com páginas completas somente.
  • Capture – Usando juntamente com o backend Static é utilizado para gerar páginas estáticas à partir de páginas dinâmicas. Portanto, as requisições subsequentes não precisam passar pelo PHP ou Zend Framework.

Tipos de backends disponíveis

  • File – Armazena os registros do cache em arquivos.
  • APC – Armazena os registros de cache em memória compartilhada pelo APC (Alternative PHP Cache).
  • Zend Server/ZendPlataform – Armazena os registro de cache usando a funcionalidade de Cache do Zend Server.
  • XCache – Armazena os registros de cache em memória compartilhada pelo XCacahe.
  • Sqllite – Armazena os registros de cache em um banco de dados SQLite.
  • Memcached/Libmemcached – Armazena os registros de cache em servidor memcached.
  • TwoLevels – Permite especificar dois outros backends para armazenar os registros de cache.
  • Static – Usando juntamente com o frontend Capture é utilizado para gerar páginas estáticas à partir de páginas dinâmicas. Portanto, as requisições subsequentes não precisam passar pelo PHP ou Zend Framework.

Exemplos

Abaixo vamos demonstrar um exemplo simples da utilização do Zend_Cache. O exemplo utiliza o frontend Core que faz cache de dados simples. Estamos utilizando o backend File para armazenar os dados. Não recomendo à utilização do backend File pois ele é mais lento do que outros backends, principalmente aqueles que utilizam memória compartilhada. Estou utilizando neste exemplo pois para você que simplesmente quer testar os exemplos não necessita de instalar programas adicionais além do php e Zend_Cache. O importante salientar é que independente do backend que você escolha, a sintaxe de utilização do Zend_Cache é totalmente transparente.

O exemplo abaixo faz o cache de um array de dados. Os dados são informações sobre usuários do sistema. Para instânciar o cache, informamos qual o frontend e qual o backend desejamos. Passamos também um array de opções para frontend e backend. Nas opções do frontend informamos que os dados devem ser serialziados antes de serem inseridos no cache, através da opção automatic_serialization. Isto evita o nosso trabalho de fazer um serialize dos dados antes de colocar no cache. Nas opções de backend informamos qual o diretório o Cache utilizará para armazenar os dados. Esta opção é obrigatória pois estamos utilizando o tipo File como backend. No caso, o diretório será /phpcache.

<?php
require_once("Zend/Cache.php");

// opcoes para frontend
$frontendOptions = array (
        'automatic_serialization' => true
);

// opcoes para backend
$backendOptions = array (
        'cache_dir' => '/phpcache'
);

// instanciar o cache
$cache = Zend_Cache::factory(
        'Core',
        'File',
        $frontendOptions,
        $backendOptions);

// utilizando o cache
$usuarios = $cache->load('usuarios');
if(!$usuarios) {
        // inserir dados no cache
        $usuarios = array(
                array('id' => 1, 'nome' => 'Manuel', 'email' => 'manuel@xxxxyy.com.br', 'telefone' => '011-1111-1111'),
        array('id' => 2, 'nome' => 'Pereira', 'email' => 'pereira@xxxxyy.com.br', 'telefone' => '011-2222-2222'),
    );
        $cache->save($usuarios, 'usuarios', array('usuario', 'admin'));
}

// dados do usuáo
echo "<pre>";
var_dump($usuarios);
echo "</pre>";

Retorno do exemplo acima:

Neste exemplo, gostaria de chamar à atenção para a função save do Zend Cache:

$cache->save($usuarios, 'usuarios', array('usuario', 'admin'));

Além de utilizarmos um identificador único para referênciar os dados no cache, ‘usuarios’, também utilizamos dois tags, ‘usuario’ e ‘admin’. Podemos portanto agrupar dados de cache através das tags. Dessa forma, podemos excluir, por exemplo, todos os dados no cache que tem associado a tag ‘admin’. Facilita a vida não ?

Limpando o Cache

Deletando todos dados no cache que possuem à tag ‘admin’ associado:

$cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('admin'));

Deletando dados do cache especificando o identificador:

$cache->remove('usuarios');

Removendo todos dados do cache de uma única vez:

$cache->clean(Zend_Cache::CLEANING_MODE_ALL);

Fazendo Cache de classes

O Frontend Class do Zend_Cache permite o cache de objetos e de métodos estáticos. No exemplo abaixo estamos fazendo o cache de um objeto da classe Usuario. Para que funcione de acordo com o esperado, definimos a opção cached_entity no bloco de opções do frontend. Dessa forma, o Zend_Cache irá fazer o cache da saída de todos métodos públicos referente ao objeto dessa classe.

<?php

require_once("Zend/Cache.php");

/*
 * Classe Usuario para exemplificar o cache de classes do Zend_Cache
 */
class Usuario {
        private $nome1 = "Jose";
        private $nome2 = "Pedro";

        public function getNome($tipo) {
                if($tipo == 1) {
                        return $this->nome1;
                } else {
                        return $this->nome2;
                }
        }
}

// opcoes para frontend
$frontendOptions = array (
        'cached_entity' => new Usuario(),
);

// opcoes para backend
$backendOptions = array (
        'cache_dir' => '/phpcache'
);

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

echo $cache->getNome(1) . PHP_EOL;
echo $cache->getNome(2) . PHP_EOL;

Resultado do exemplo acima:

Perceba que estamos chamando o método getNome() através da instância do Zend_Cache e não da instância da classe Usuario. A instância do Zend_Cache funciona como um proxy para a classe Usuario. Na primeira vez que chamarmos o método getNome(1), o cache irá chamar o método original. Nas chamadas subsequentes, o resultado virá do cache. O interessante à observar aqui é que o Zend_Cache reconhece os parâmetros passados para os métodos. Portanto getNome(1) será armazenado separadamente de getNome(2) dentro do cache. Inteligente não ?

Conclusão

Realmente me surpreendi com as funcionalidades disponíveis pelo Zend_Cache. É um sistema de cache extremamente flexível, fácil de configurar e muito poderoso. Para se aprofundar mais a documentação oficial do Zend Framework é a melhor opção. Lá você encontrará exemplos de utilização com todos tipos de frontend e backend.

http://framework.zend.com/manual/en/zend.cache.html

Please follow and like us:

Comments

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: