Muitas vezes quando criamos um site e por pelas mais diversas razões surge necessidade de recorrer a um mecanismo de cache, uma das principais razões é a performance.
E em que é que cache influencia a performance? Imagina-se o ficheiro teste.php com 500 linhas de código com ligações a MySQL etc etc, é mais rápido se o ficheiro de output já estiver “feito” e só o actualizar de x em x temp, senão cada pedido seria 500 linhas de código assim serão 10 ou 20 conforme o mecanismo de cache a usar, temos que ter em conta que se nesse código existirem queries ao MySQL isso degrada ainda mais a performance.
Estou a criar uma classe de cache que de uma forma muito simples faz cache do output de qualquer script php inclusive se este tiver dados passados pelo método GET.
A classe pode ser muitissimo melhorada para já só faz o que se propõe que é verificar se um ficheiro já se encontra em cache, se o mesmo estiver cria o output para o cliente, se ainda não existir cache é criado um buffer com o output da página pedida e cria um ficheiro em cache com o conteúdo do mesmo, que será servido no próximo pedido…
O código da minha classe é o seguinte:
O post está dividido porque é muito extenso!!…
<?php
/*
Criado por Antonio Campos
CHANGELOG
04-01-2008
-> Primeiro release!
*/
class Cache{
function Cache()
{
//Directório onde queremos guardar os ficheiros de cache
$this->directorio_cache = “cache/”; //Agora vamos começar a contruir uma string que irá conter o nome so script que vamos fazer cache
$this->pagina = $_SERVER[‘SCRIPT_NAME’].“/”;
//se existir uma query string vamos concatenar a mesma com o nome do ficheiro
if (isset($_SERVER[‘QUERY_STRING’]))
{
$this->pagina=$this->pagina.$_SERVER[‘QUERY_STRING’];
}
}
function Inicio()
{
//Gerar o nome do ficheiro de cache correspondente á página que estamos
//O MD5 é só para evitar que o nome contenha careteres inválidos por exemplo ? e & comuns nas query strings
//coloquei a extenssão html podem colocar o que quiserem
$this->ficheiro_cache = $this->directorio_cache . md5($this->pagina) . ‘.html’;
//Verificar se o ficheiro já existe na cache
if (file_exists($this->ficheiro_cache))
{
//se já existir lê-mos o mesmo e geramos o output
readfile($this->ficheiro_cache);
//como já fizemos output não queremos que mais nada seja executado!
exit();
}
//se chegar aqui é porque o ficheiro não existia em cache e temos que o criar
//esta função cria um buffer onde é colocado o outup que é igualmente enviado ao cliente
ob_start();
}
function Fim()
{
// Como não exise o ficheiro na cache vamos cria-lo e abrir em modo w (w de write)
$fp = fopen($this->ficheiro_cache, ‘w’);
//Escrevemos o conteudo do buffer no novo ficheiro de cache
@fwrite($fp, ob_get_contents());
//Esta parte não é necessária é só escrever no fim do ficheiro a data e hora em que o mesmo foi gerado
$hora = date(‘h:i:s, j-m-Y’);
@fwrite($fp, “<!– Cache – $this->pagina – $hora –>”);
//fechamos o apontador para o ficheiro
@fclose($fp);
//e fechamos tamb+em o buffer criado
ob_end_flush();
}
function Limpar()
{
//criamos um apontador para o directorio onde esta guardada a cache
if ($handle = $this->directorio_cache)
{
//um ciclo que percorre todos os ficheiros
while (false !== ($file = readdir($handle)))
{
//evitar um erro!!
if ($file != ‘.’ and $file != ‘..’)
{
//Só uma informação
echo ‘Apagado –> ‘.$file . ‘<br>’;
//apagar cada um dos ficheiros
unlink($this->directorio_cache . ‘/’ . $file);
}
}
//fechamos o apontador
closedir($handle);
}
}
}
?>
Um bocado desformatado mas ai fica ele, um exemplo de utilização será:
<?php
//incluir o ficheiro onde temos a classe
include_once "class.cache.php";
$cache = new Cache;
//Iniciar o processo de cache
$cache->Inicio();
//Se o ficheiro ja existir em cache nada mais sera executado abaixo desta linha
?>
<html>
<head>
<title>Exemplo de Cache em Php</title>
</head>
<body>
<h1>Conteudo da pagina</h1>
</body>
</html>
<?php
//Se chegou aqui é porque não existia em cache, por isso vamos chamar a função que escreve o ficcheiro na cache!
$cache->Fim();
?>
Também deformado!
Claro que esta classe está muito incompleta idealmente deveria existir um controlo da idade da cache ou uma definição do prazo da mesma!
Estejam á vontade para a melhorar!