Quem aqui nunca atualizou uma página web, alterou um CSS, JS ou imagem, enviou e-mail para o cliente e ele disse que na máquina dele não aparece?
Eu consegui ganhar esta batalha e de uma forma muito boa e ainda melhorar o pagespeed dos meus sites. Como? Muito simples.
Para este exemplo não se esqueça que a pasta site_cache precisa de permissão de escrita.
Primeiro eu criei uma classe CompilaCss e nesta classe fiz a seguinte estrutura:
<?php
class CompilaCss
{
private $css = array();
private $filemtime = 0;
private $file = '';
public function addCss( $cssName )
{
$this->css[] = $cssName;
// Soma todos as datas de alterações do arquivo
// Aqui esta a mágica. Mudando algum CSS a soma dos filemtime serão
// diferentes
$this->filemtime += filemtime( $cssName );
}
public function linkCss( $base )
{
$this->file = 'site_cache/css_' . md5( $this->filemtime ) . '.css';
if( !file_exists( $this->file ))
{
// Se o arquivo do CSS ainda não existir, cria outro.
// Basicamente se mudar algum filemtime de qualquer arquivo
// um novo arquivo é criado
$this->createCssFile();
}
echo '<link href="' . $base . $this->file . '" rel="stylesheet" type="text/css" />';
}
private function createCssFile()
{
$salvaCSS = '';
foreach ( $this->css as $css )
{
// Pega o conteúdo dos arquivos CSS
// adiciona todos os conteúdos a variável $salvaCSS
$salvaCSS .= file_get_contents( $css );
}
// Retira todos os comentários
$salvaCSS = preg_replace('!/\*.*?\*/!s', ' ', $salvaCSS);
// Retira todos os espaços em branco e quebras de linhas
$salvaCSS = preg_replace('/\s+/', ' ', $salvaCSS);
// espaços extras
$salvaCSS = str_replace(' :', ':', $salvaCSS);
$salvaCSS = str_replace('; ', ';', $salvaCSS);
$salvaCSS = str_replace(': ', ':', $salvaCSS);
$salvaCSS = str_replace(' {', '{', $salvaCSS);
$salvaCSS = str_replace('{ ', '{', $salvaCSS);
$salvaCSS = str_replace(' }', '}', $salvaCSS);
$salvaCSS = str_replace('} ', '}', $salvaCSS);
$salvaCSS = str_replace(';} ', '}', $salvaCSS);
// Salva
file_put_contents( $this->file, $salvaCSS );
}
}
Veja que em addCss($cssName) eu apenas adiciono todos os CSS em um array e acrescento o valor do filemtime do arquivo á $this->filemtime.
Já foi possível perceber que se eu alterar qualquer arquivo CSS o filemtime será diferente e por padrão teremos uma soma diferente.
Para adicionarmos CSS fazemos assim:
<?php
$css = new CompilaCss();
$css->addCss('css/erro.css');
$css->addCss('css/style.css');
$css->addCss('modulos/lightbox/css/jquery.lightbox-0.5.css');
$css->addCss( 'css/style-print.css' );
$css->linkCss( URL::getBase() );
Parte do site www.cidadedesaobonifacio.com.br. Qualquer um dos CSS acima podem ser acessados normalmente prefixando com o domínio.
Ex: www.cidadedesaobonifacio.com.br/css/style-print.css
Sempre que for chamado $css->linkCss( URL::getBase() ); a classe verificará se o arquivo já compilado existe e se não existe criará um arquivo novo. Se já existe apenas retorna o link. Caso não exista primeiro compila o arquivo e depois retorna o link.
O método createCssFile() além de unir todos os CSS em um único arquivo, também remove os caracteres em branco sobrando, retira os comentários e as quebras de linha.
Veja este sistema funcionando em: php.eduardokraus.com/code/10044/ e o fonte esta em php.eduardokraus.com/code/10044/10044.zip.