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!

9 comentários em “Sistema simples de cache com PHP…”

  1. Antônio,

    muito boa tua classe. Estou utilizando em um portal que desenvolvi e que tinha alguns problemas de performance. Implementei nela a funcionalidade do tempo de vida do cache, como um parâmetro configurável. Eu posso publicar em meu blog, para que os outros tenham acesso? Manterei todos os créditos, sem problema nenhum.

    Abraços

  2. Podes usar á vontade!!!

    Também a estou a usar e para já ainda não tive nenhum problema, pelo contrario já resolveu alguns!!!!

    Se quiseres envia-me a classe com as alterações que eu publico aqui no blog, e dou-te os respectivos creditos.

  3. No cache ele criar um arquivo assim. bc7a07acb02bad8dfcc44756b0aa1b8b.html. Tem jeito de mudar isso?

    Eu queria colocar assim. data_template_index.php.html

  4. desculpe amigo eu to na minha fase de estudo ,me parece que existem um tipo de cache que e gerado no htacsess do apache
    vc ja avaliou esse tipo de solucao /
    um abraçao pra t
    henrique guedes

  5. Gostei muito dessa classe, agora.. tpw.. gostaria de saber se tinha como medir a velocidade do site…

    tpw.. antes e depois!!

  6. Nossa classe perfeita, apesar de como você disse, dela estar meio incompleta, ela é bem simples para estudos, ou seja apartir dela desenvolver, aplicações em metodos diferentes =)

    Parabens mesmo.

Os comentários estão fechados.