Site icon António Campos

Sistema simples de cache com PHP…

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!

Exit mobile version