Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

356 lines
17 KiB

Cache de Dados
============
O Cache de Dados é responsável por armazenar uma ou mais variáveis PHP em um arquivo temporário para
ser recuperado posteriormente.
Este também é a fundação para funcionalidades mais avançadas do cache, como [cache de consulta](#query-caching)
e [cache de página](caching-page.md).
O código a seguir é um padrão de uso típico de cache de dados, onde `$cache` refere-se a
um [Componente de Cache](#cache-components):
```php
// tentar recuperar $data do cache
$data = $cache->get($key);
if ($data === false) {
// $data não foi encontrado no cache, calculá-la do zero
// armazenar $data no cache para que esta possa ser recuperada na próxima vez
$cache->set($key, $data);
}
// $data é acessível a partir daqui
```
## Componentes de Cache <span id="cache-components"></span>
O cache de dados se baseia nos, então chamados, *Componentes de Cache* que representam vários armazenamentos de cache,
como memória, arquivos, bancos de dados.
Componentes de Cache são normalmente registrados como [componentes de aplicação](structure-application-components.md) para que possam ser globalmente configuráveis e acessíveis. O código a seguir exibe como configurar o componente de aplicação `cache` para usar [memcached](http://memcached.org/) com dois servidores de cache:
```php
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'servidor1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'servidor2',
'port' => 11211,
'weight' => 50,
],
],
],
],
```
Você pode então, acessar o componente de cache acima usando a expressão `Yii::$app->cache`.
Já que todos os componentes de cache suportam as mesmas APIs, você pode trocar o componente de cache por outro
reconfigurando-o nas configurações da aplicação sem modificar o código que usa o cache.
Por exemplo, você pode modificar a configuração acima para usar [[yii\caching\ApcCache|APC cache]]:
```php
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],
```
> Dica: Você pode registrar múltiplos componentes de cache na aplicação. O componente chamado `cache` é usado
por padrão por muitas classes dependentes de cache (ex., [[yii\web\UrlManager]]).
### Sistemas de Cache Suportados <span id="supported-cache-storage"></span>
Yii suporta uma ampla gama de sistemas de cache. A seguir um resumo:
* [[yii\caching\ApcCache]]: usa a extensão do PHP [APC](http://php.net/manual/en/book.apc.php). Esta opção pode ser
considerada a mais rápida ao se implementar o cache de uma aplicação densa e centralizada (por exemplo, um
servidor, sem balanceadores de carga dedicados, etc.).
* [[yii\caching\DbCache]]: usa uma tabela no banco de dados para armazenar os dados em cache. Para usar este cache
você deve criar uma tabela como especificada em [[yii\caching\DbCache::cacheTable]].
* [[yii\caching\DummyCache]]: serve apenas como um substituto e não faz nenhum cache na realidade.
O propósito deste componente é simplificar o código que precisa checar se o cache está disponível.
Por exemplo, durante o desenvolvimento, se o servidor não suporta cache, você pode configurar um
componente de cache para usar este cache. Quando o suporte ao cache for habilitado, você pode trocá-lo
para o componente correspondente. Em ambos os casos, você pode usar o mesmo código
`Yii::$app->cache->get($key)` para tentar recuperar os dados do cache sem se procupar que
`Yii::$app->cache` possa ser `null`.
* [[yii\caching\FileCache]]: usa arquivos para armazenar os dados em cache. Este é particularmente indicado
para armazenar grandes quantidades de dados como o conteúdo da página.
* [[yii\caching\MemCache]]: usa o [memcache](http://php.net/manual/en/book.memcache.php) do PHP e as extensões
[memcached](http://php.net/manual/en/book.memcached.php). Esta opção pode ser considerada a mais rápida
ao se implementar o cache em aplicações distribuídas (ex., vários servidores, balanceadores de carga, etc.)
* [[yii\redis\Cache]]: implementa um componente de cache baseado em armazenamento chave-valor
[Redis](http://redis.io/) (requer redis versão 2.6.12 ou mais recente).
* [[yii\caching\WinCache]]: usa a extensão PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)
([veja também](http://php.net/manual/en/book.wincache.php)).
* [[yii\caching\XCache]]: usa a extensão PHP [XCache](http://xcache.lighttpd.net/).
* [[yii\caching\ZendDataCache]]: usa
[Cache de Dados Zend](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm)
como o meio de cache subjacente.
> Dica: Você pode usar vários tipos de cache na mesma aplicação. Uma estratégia comum é usar caches baseados
em memória para armazenar dados pequenos mas constantemente usados (ex., dados estatísticos), e usar caches
baseados em arquivo ou banco da dados para armazenar dados que são maiores mas são menos usados
(ex., conteúdo da página).
## APIs De Cache <span id="cache-apis"></span>
Todos os componentes de caches estendem a mesma classe base [[yii\caching\Cache]] e assim suportam as seguintes APIs:
* [[yii\caching\Cache::get()|get()]]: recupera um registro no cache usando uma chave específica.
Retorna `false` caso o item não for encontrado no cache ou se o registro está expirado/invalidado.
* [[yii\caching\Cache::set()|set()]]: armazena um registro no cache identificado por uma chave.
* [[yii\caching\Cache::add()|add()]]: armazena um registro no cache identificado por uma chave se a chave não
for encontrada em cache.
* [[yii\caching\Cache::mget()|mget()]]: recupera múltiplos registros do cache com as chaves especificadas.
* [[yii\caching\Cache::mset()|mset()]]: armazena múltiplos registros no cache. Cada item identificado por uma chave.
* [[yii\caching\Cache::madd()|madd()]]: armazena múltiplos registros no cache. Cada item identificado por uma chave.
Se a chave já existir em cache, o registro é ignorado.
* [[yii\caching\Cache::exists()|exists()]]: retorna se a chave específica é encontrada no cache.
* [[yii\caching\Cache::delete()|delete()]]: remove um registro do cache identificado por uma chave.
* [[yii\caching\Cache::flush()|flush()]]: remove todos os registros do cache.
> Observação: Não armazene o valor boleano `false` diretamente, porque o método [[yii\caching\Cache::get()|get()]] retorna `false`para indicar que o registro não foi encontrado em cache. Você pode armazena `false` em um array e armazenar este em cache para evitar este problema.
Alguns tipos de cache como MemCache, APC, suportam recuperar em lote múltiplos registros em cache, o que poder reduzir
o custo de processamento envolvido ao recuperar informações em cache. As APIs [[yii\caching\Cache::mget()|mget()]]
e [[yii\caching\Cache::madd()|madd()]] são equipadas para explorar esta funcionalidade. Em caso do cache em questão não suportar esta funcionalidade, ele será simulado.
Como [[yii\caching\Cache]] implementa `ArrayAccess`, um componente de cache pode ser usado como um array. A seguir alguns exemplos:
```php
$cache['var1'] = $valor1; // equivalente a: $cache->set('var1', $valor1);
$valor2 = $cache['var2']; // equivalente a: $valor2 = $cache->get('var2');
```
### Chaves de Cache <span id="cache-keys"></span>
Cada registro armazenado no cache é identificado por uma chave única. Quando você armazena um registro em cache,
você deve especificar uma chave para ele. Mais tarde, quando você quiser recuperar o registro do cache, você deve
fornecer a chave correspondente.
Você pode usar uma string ou um valor arbitrário como uma chave do cache. Quando a chave não for uma string, ela será
automaticamente serializada em uma string.
Uma estratégia comum ao definir uma chave de cache é incluir todos os fatores determinantes na forma de um array.
Por exemplo, [[yii\db\Schema]] usa a seguinte chave para armazenar a informação de um esquema de uma tabela do banco
de dados.
```php
[
__CLASS__, // nome da classe do esquema
$this->db->dsn, // nome da fonte de dados da conexão BD
$this->db->username, // usuario da conexão BD
$name, // nome da tabela
];
```
Como você pode ver, a chave inclui toda a informação necessária para especificar unicamente uma tabela do banco.
Quando o cache de diferentes aplicações é armazenado no mesmo lugar, é aconselhável especificar, para cada
aplicação, um prefixo único a chave do cache para evitar conflitos entre elas. Isto pode ser feito ao configurar
a propriedade [[yii\caching\Cache::keyPrefix]]. Por exemplo, na configuração da aplicação você pode escrever o seguinte código:
```php
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'minhaapp', // um prefíxo de chave único
],
],
```
Para assegurar interoperabilidade, apenas caracteres alfanuméricos devem ser usados.
### Expiração de Cache <span id="cache-expiration"></span>
Um registro armazenado em cache não será apagado a menos que seja removido por alguma política aplicada
(por exemplo, espaço determinado para o cache esteja cheio e os registros mais antigos sejam removidos). Para alterar
estes comportamento, você pode fornecer um parâmetro de expiração ao chamar [[yii\caching\Cache::set()|set()]]
para armazenar um registro. O parâmetro indica por quantos segundos um registro pode permanecer validado no cache.
Quando você chamar [[yii\caching\Cache::get()|get()]] para recuperar um registro, se o tempo de expiração houver passado, o método retornará `false`, indicando que o registro não foi encontrado no cache. Por exemplo,
```php
// Manter o registro em cache por até 45 segundos
$cache->set($chave, $registro, 45);
sleep(50);
$data = $cache->get($chave);
if ($registro === false) {
// $registro está expirado ou não foi encontrado no sistema
}
```
### Dependências de Cache <span id="cache-dependencies"></span>
Além da definição de expiração, um registro em cache pode também ser invalidado por mudanças nas, então chamadas,
*dependências de cache*. Por exemplo, [[yii\caching\FileDependency]] representa a dependência na data de modificação
de um arquivo.
Quando esta dependência muda, significa que o arquivo correspondente foi mudado. Como um resultado, qualquer
arquivo com data ultrapassada encontrado no cache deve ser invalidado e a chamada de [[yii\caching\Cache::get()|get()]]
retornará `false`.
Dependências de Cache são representadas como objetos de classes dependentes de [[yii\caching\Dependency]]. Quando você chamar [[yii\caching\Cache::set()|set()]] para armazenar um registro em cache, você pode passar um objeto de dependência. Por exemplo,
```php
// Criar uma dependência sobre a data de modificação do arquivo exemplo.txt.
$dependencia = new \yii\caching\FileDependency(['fileName' => 'exemplo.txt']);
// O registro expirará em 30 segundos.
// Ele também pode ser invalidado antes, caso o exemplo.txt seja modificado.
$cache->set($key, $data, 30, $dependency);
// O cache verificará se o registro expirou.
// E também verificará se a dependência associada foi alterada.
// Ele retornará false se qualquer uma dessas condições seja atingida.
$data = $cache->get($key);
```
Abaixo um sumário das dependências de cache disponíveis:
- [[yii\caching\ChainedDependency]]: a dependência muda caso alguma das dependências na cadeia for alterada.
- [[yii\caching\DbDependency]]: a dependência muda caso o resultado da consulta especificada pela instrução SQL seja
alterado.
- [[yii\caching\ExpressionDependency]]: a dependência muda se o resultado da expressão PHP especificada for alterado.
- [[yii\caching\FileDependency]]: A dependência muda se a data da última alteração do arquivo for alterada.
- [[yii\caching\TagDependency]]: associa um registro em cache com uma ou múltiplas tags. Você pode invalidar os
registros em cache com a tag especificada ao chamar [[yii\caching\TagDependency::invalidate()]].
## Cache de Consulta <span id="query-caching"></span>
Cache de consulta é uma funcionalidade especial de cache construída com o cache de dados. Ela é fornecida para armazenar em cache consultas ao banco de dados.
O cache de consulta requer uma [[yii\db\Connection|conexão ao banco de dados]] e um [componente de aplicação](#cache-components) de `cache` válido.
A seguir uma utilização básica do cache de consulta, assumindo que `$bd` é uma instância de [[yii\db\Connection]]:
```php
$resultado = $bd->cache(function ($bd) {
// O resultado da consulta SQL será entregue pelo cache
// se o cache de consulta estiver sido habilitado e o resultado da consulta for encontrado em cache
return $bd->createCommand('SELECT * FROM clientes WHERE id=1')->queryOne();
});
```
Cache de consulta pode ser usado pelo [DAO](db-dao.md) da mesma forma que um [ActiveRecord](db-active-record.md):
```php
$resultado = Cliente::getDb()->cache(function ($bd) {
return Cliente::find()->where(['id' => 1])->one();
});
```
> Informação: Alguns SGBDs (ex., [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html))
também suportam o cache de consulta no servidor. Você pode escolher usá-lo ao invés do mecanismo de cache
de consulta.
O cache de consulta descrito acima tem a vantagem de poder especificar dependências de cache flexíveis
e assim sendo potencialmente mais eficiente.
### Configurações <span id="query-caching-configs"></span>
Cache de consulta tem três opções configuráveis globalmente através de [[yii\db\Connection]]:
* [[yii\db\Connection::enableQueryCache|enableQueryCache]]: Configura se o cache de consulta está habilitado.
O padrão é true. Observe que para ter efetivamente o cache de consulta habilitado, você também deve ter um cache válido como especificado por [[yii\db\Connection::queryCache|queryCache]].
* [[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: representa o número de segundos que o resultado de uma
consulta pode se manter válido em cache. Você pode usar 0 para indicar que o resultado da consulta deve permanecer no
cache indefinidamente. Este é o valor padrão usado quando [[yii\db\Connection::cache()]] é chamado sem nenhuma
especificação de duração.
* [[yii\db\Connection::queryCache|queryCache]]: representa a ID do componente de aplicação de cache.
Seu padrão é `'cache'`. Cache de consulta é habilitado apenas se houver um componente de aplicacão de cache válido.
### Usando o Cache de Consulta <span id="query-caching-usages"></span>
Você pode usar [[yii\db\Connection::cache()]] se tiver múltiplas consultas SQL que precisam ser armazenadas no
cache de consulta. Utilize da seguinte maneira,
```php
$duracao = 60; // armazenar os resultados em cache por 60 segundos
$dependencia = ...; // alguma dependência opcional
$result = $db->cache(function ($db) {
// ... executar consultas SQL aqui ...
return $result;
}, $duracao, $dependencia);
```
Qualquer consulta SQL na função anônima será armazenada em cache pela duração especificada com a dependência informada. Se o resultado da consulta for encontrado em cache e for válido, a consulta não será necessária e o
resultado será entregue pelo cache. Se você não especificar o parâmetro `$duracao`, o valor de
[[yii\db\Connection::queryCacheDuration|queryCacheDuration]] será usado.
Ocasionalmente em `cache()`, você pode precisar desabilitar o cache de consulta para algumas consultas em particular. Você pode usar [[yii\db\Connection::noCache()]] neste caso.
```php
$result = $db->cache(function ($db) {
// consultas SQL que usarão o cache de consulta
$db->noCache(function ($db) {
// consultas SQL que não usarão o cache de consulta
});
// ...
return $result;
});
```
Se você apenas deseja usar o cache de consulta para apenas uma consulta, você pode chamar [[yii\db\Command::cache()]]
ao construir o comando. Por exemplo,
```php
// usar cache de consulta e definir duração do cache para 60 segundos
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();
```
Você pode também usar [[yii\db\Command::noCache()]] para desabilitar o cache de consulta para um único comando, Por exemplo,
```php
$result = $db->cache(function ($db) {
// consultas SQL que usam o cache de consulta
// não usar cache de consulta para este comando
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();
// ...
return $result;
});
```
### Limitações <span id="query-caching-limitations"></span>
O cache de consulta não funciona com resultados de consulta que contêm <i>manipuladores de recursos</i> (resource handlers).
Por exemplo, ao usar o tipo de coluna `BLOB` em alguns SGBDs, o resultado da consulta retornará um <i>manipulador de recurso</i> (resource handler) para o registro na coluna.
Alguns armazenamentos em cache têm limitações de tamanho. Por exemplo, memcache limita o uso máximo de espaço de 1MB para cada registro. Então, se o tamanho do resultado de uma consulta exceder este limite, o cache falhará.