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.