Antes de entrarmos de cabeça em uma das partes que eu acho mais interessante do Smarty Cache, uma coisa que deveria ter sido apresentada no último artigo era como limpar o cache.
Por falta de um lugar melhor, aqui vai.
<?
require('Smarty.class.php');
$Smarty = new Smarty;
$Smarty->caching = true;
// OPCAO 1 - Limpar todos o cache
$smarty->clear_all_cache();
// OPCAO 2 - Limpar somente o cache de um template
$smarty->clear_cache('aleatorio.tpl');
$smarty->display('index.tpl');
?>
Como você pode ver temos duas possibilidades, opção 1 permite limpar todos os caches do site em um único comando, e a opção 2 permite que você limpe o cache de um template individual.
Sugiro que você tome um certo cuidado ao utilizar o comando cleal_all_cache() pois em servidores com alta visitação, você repentinamente ter que gerar todos os arquivos de cache pode causar um impacto indesejado no site. Planeje suas mudanças de cache cuidadosamente. Mais nesse assunto depois.
Muitos caches, um template.
Uma das perguntas que eu mais ouvi ser feita (não somente com relação ao artigo mas nas empresas onde trabalhei com Smarty) foi em relação ao controle de de exibição do cache. Vou exemplificar usando o cenário similar ao explicado em um comentário no meu primeiro artigo:
Um template de Menu (menu.tpl) entra no cache. Quando o usuário está logado, o menu muda para não incluir os campos de login e senha, substituindo-os por um link de "logoff".
Uma típica solução para um cenário desses seria algo assim:
<?
// includes e instancia do Smarty
// Checa se o usuario está logado
$logadoID = isset($_SESSION['id_logado'])?$_SESSION['id_logado']:false;
if (!$logado){
$Smarty->clear_cache('menu.tpl');
$Smarty->assign('mostraLogin',true);
$Smarty->assign('usuarioNome','Visitante');
}else{
$Smarty->clear_cache('menu.tpl');
$Smarty->assign('mostraLogin',false);
$Smarty->assign('usuarioNome',$_SESSION['nome_logado']);
}
$Smarty->display('menu.tpl');
?>
(eu resumi um pouco os códigos, pois já presumo que você saiba fazer o include do Smarty, setar o cache=1 etc....)
O código acima deveria funcionar relativamente bem, porém, ele tem não tão obvio.
O menos obvio é que toda vez que rodamos esse PHP, checamos por uma sessão chamada "id_logado" e decidimos o que fazer a partir dela. Vamos fazer um simulado pra ver o que acontece:
1 - Visitante
- entra ná pagina, ele não tem id_logado, limpa o cache, monta o menu, mostra o display
2 - Novo Visitante
- entra ná pagina, ele tbm não tem "id", limpamos o cache, monta o menu, e mostra o display
3 - usuario logado - o usuario tá logado, limpamos o cahce, montamos o menu, e mostrams o display.
Bom sem continuar, vemos que de fato, embora estamos usando o cache, na realidade, estamos apenas gerando mais trabalho para o processador, sendo que toda vez estamos limpando o cache. Esquecemos de utilizar o is_cached para checar se o template está cacheado ou não. Então vamos lá:
<?
// includes e instancia do Smarty
// Checa se o usuario está logado
$logadoID = isset($_SESSION['id_logado'])?$_SESSION['id_logado']:false;
if (!$logado){
if (!$Smarty->is_cached('menu.tpl')){
$Smarty->clear_cache('menu.tpl');
$Smarty->assign('mostraLogin',true);
$Smarty->assign('usuarioNome','Visitante');
}
}else{
if (!$Smarty->is_cached('menu.tpl')){
$Smarty->clear_cache('menu.tpl');
$Smarty->assign('mostraLogin',false);
$Smarty->assign('usuarioNome',$_SESSION['nome_logado']);
}
}
$Smarty->display('menu.tpl');
?>
Agora geramos outro problema: De novo aos testes:
1 - visitante - não tem id, não tem cache, seta valores, mostra display
2 - visitante - nao tem id, o cache existe, mostra display
3 - visitante - nao tem id, o cache existe, mostra display
(legal com o visitante funcionou)
4 - usuario - tem ID, cache existe!, mostra display
...
Pronto como resolvemos isso? O Smarty guarda o primeiro cache, independente de termos logado ou não... assim todo mundo ve a página com o formulário de login.
Eu demorei, mas é importante que você entenda em detalhe a lógica por trás do Smarty para evitar problemas enquanto desenvolve. É muito comum você(eu ou qualquer um) fazer esse tipo de erro ao desenvolver, e por isso, fazer simulados com pequenos pedaços de código enquanto você desenvolve é importante.
Como resolvemos esse problema? Com cache dinâmico.
O cache dinâmico (por falta de melhor nome), permite você levar em consideração variáveis na hora de cachear seus arquivos. Vamos ao código, depois a explicação:
<?
// includes e instancia do Smarty
// Checa se o usuario está logado
$logadoID = isset($_SESSION['id_logado'])?$_SESSION['id_logado']:false;
if (!$logado){
if (!$Smarty->is_cached('menu.tpl',$logadoID)){
// Não vamos limpar o cache pq não tem cache
//$Smarty->clear_cache('menu.tpl',$logadoID);
$Smarty->assign('mostraLogin',true);
$Smarty->assign('usuarioNome','Visitante');
}
}else{
if (!$Smarty->is_cached('menu.tpl',$logadoID)){
// Não vamos limpar o cache pq não tem
//$Smarty->clear_cache('menu.tpl',$logadoID);
$Smarty->assign('mostraLogin',false);
$Smarty->assign('usuarioNome',$_SESSION['nome_logado']);
}
}
$Smarty->display('menu.tpl',$logadoID);
?>
Tá onde que mudamos? Eu adicionei a variável $logadoID como parâmetro dos metodos is_cached(), clear_cache() e display().
Agora vamos lá aos testes:
1 - visitante - não tem id, não tem cache menu.tpl0, seta valores, mostra display
2 - visitante - nao tem id, o cache menu.tpl0 existe, mostra display
3 - visitante - nao tem id, o cache menu.tpl0 existe, mostra display
4 - usuario 5 - tem ID = 5, o cache menu.tpl5 não existe, seta valores, mostra display
5 - usuario 5 - tem ID = 5, o cache menu.tpl5 existe, mostra display
6 - visitante - nao tem id, o cache menu.tpl0 existe, mostra display
7 - usuario 9 - tem ID = 9, o cache menu.tpl9 não existe, seta valores, mostra display
8 - usuario 5 - tem ID = 5, o cache menu.tpl5 existe, mostra display
8 - usuario 9 - tem ID = 9, o cache menu.tpl9 existe, mostra display
Pelos testes, parece que tudo funcionou!
Eu deixei a linha comentada do clear_cache porque é importante que você veja que no minuto que se usa o cache dinâmico, as funções que trabalham os templates precisam ter o "ID" associadas a elas.
Agora você deve estar perguntando porque eu demorei tanto para explicar algo que tão simples.
Usar o cache dinâmico em certos casos é imprescindível, você não tem como fazer algo assim sem ele, mas um "erro" muito comum dos desenvolvedores de Smarty é sair colocando ID em tudo que é cache. È importante lembrar que todo cache é um arquivo em disco, e que usando o cache dinâmico, você aumenta o número de arquivos existente no seu HD.
Isso pode não parecer um problema muito sério, mas depois de algum tempo, e em um site grande, você pode ter literalmente milhões de arquivos cache. Se você cachear uma página que não muda com um ID, você acabará tendo centenas de milhares de cópias do mesmo arquivo, gastando espaço desnecessariamente.
O Cache dinâmico tem uma funcionalidade bem interessante. É possível apagar todos os caches com um ID=X. Usando o nosso exemplo acima, poderíamos apagar dodos os caches do usuário com ID=9.
Para tal, basta executar o comando:
$Smarty->clear_cache(null, $logadoID);
Bom é isso. No próximo artigo, eu explicarei como funciona o agrupamento de caches, e se der darei alguns casos de uso para vocês terem na cabeça na hora de sair desenvolvendo.