Posted: December 25th, 2008 | Author: Felipe Ribeiro | Filed under: apache, php, web 2.0 | Tags: apache, php, web 2.0 | 14 Comments »
Caching é fundamental para a escalabilidade de aplicações Web. Existem diversas ferramentas que oferecem diferentes maneiras de se fazer isso, seja no Smarty, no APC, nos diversos frameworks, ou Memcached para os mais drásticos…
Mas essa é a “maneira Rasmus Lerdorf” de se fazer cache com PHP sem nenhuma ferramenta externa e com uma sacada fenomenal.
Para um servidor Web é muito mais rápido servir arquivos estáticos do que esperar que aquele arquivo seja interpretado por algum módulo ou que seja executado em CGI e é isso que esse método faz, gera arquivos estáticos sob demanda, utilizando os recursos que o Apache oferece.
Agora imagine que você tem um site de notícias e quer que elas sejam tratadas como arquivos estáticos, e os links para cada notícia seria algo como:
http://meusite.com.br/noticias/000001.html
1º passo: Setamos nas configurações do Apache para que a página de erro 404 seja um arquivo .php (isso pode ser feito no .htaccess da pasta ou nas configurações do Apache propriamente dito). No caso do .htaccess, basta colocar isso:
ErrorDocument 404 /noticias/gera_cache.php
2º passo: Criamos o arquivo gera_cache.php, que irá tratar as requisições que teriam como resposta o erro 404 (Not Found) com o seguinte codigo:
<?php
$id = basename($_SERVER['REDIRECT_URL'], '.html');
/* Acessa a página dinâmica */
$html = file_get_contents(sprintf("http://meusite.com.br/noticias.php?id=%d",$id));
/* O ideal é fazer algum tratamento de erros, para evitar a
criação de arquivos para ids inválidos */
/* Exibe o conteúdo */
header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));
echo $html;
/* Salva o conteúdo em um arquivo .html */
$fp = fopen(sprintf(dirname(__FILE__)."/%d.html", $id), "w");
fputs($fp, $html);
fclose($fp);
?>
Sendo assim, o que vai acontecer:
Quando o usuário acessar pela primeira vez o link http://meusite.com.br/noticias/000001.html, o arquivo /noticias/000001.html não existirá e o usuário será redirecionado para o gera_cache.php. O gera_cache.php acessa a página dinâmica que exibe o conteúdo da página com o id passado (000001) e salva em um html. Nos acessos consecutivos ao http://meusite.com.br/noticias/000001.html o arquivo existirá e não passará mais pelo PHP.
É uma técnica bem “tricky” e que precisa de cuidados, por exemplo, você precisa ter uma rotina que expira os arquivos em cache após algum tempo e quando houver alguma alteração em determinada informação que interfere na página que está em cache, para garantir consistência dos dados. Uma maneira muito simples de se fazer isso é usando a função filectime do PHP para checar a idade dos arquivos em uma rotina que rodaria em background e apagaria os que fossem mais velhos que o tempo desejado. Mas funciona muito bem!
P.S.: Um artigo que li dizia que apesar dessa técnica ter se tornado pública através do Rasmus, ela foi criada mesmo pelo Stig Bakken
Posted: July 16th, 2008 | Author: Felipe Ribeiro | Filed under: apache, funny, geeky | Tags: apache, comics, funny, geeky | No Comments »
Só para tirar as teias de aranha enquanto não tenho tempo de escrever nada.

Posted: February 16th, 2008 | Author: Felipe Ribeiro | Filed under: apache, desenvolvimento de software, php, ruby | Tags: apache, desenvolvimento de software, php, ruby | No Comments »
“Quem cola não sai da escola”, é o ditado que a gente escuta no colégio, mas Cheat sheets e guias de bolso realmente são muito úteis quando você quer o nome daquela funçãozinha que faz exatamente o que você quer e você não lembra no momento, para consultas rápidas e não pra quem quer realmente aprender algo.
Achei algumas bem interessantes e vou compartilhar aqui até para facilitar de me lembrar depois (uma Cheat sheet de cheat sheets
):
Posted: January 29th, 2008 | Author: Felipe Ribeiro | Filed under: apache, desenvolvimento de software, php, regex | Tags: apache, desenvolvimento de software, php, regex | No Comments »
Você tem medo de REGEX!? Eu também!
Nos últimos tempos tenho lidado bastante com REGEX editando regras do Apache mod_rewrite e com a classe que publiquei no PHPClasses, a SiteMapGenerator Tabajara, que se propõe a gerar um mapa do site em xml no padrão estabelecido pelo Google para melhorar a indexação.
Mas depois de tirar onda da galera do Perl no post anterior, vou exaltar a importância que expressões regulares têm nas nossas validações, e para isso vou citar as 8 expressões regulares que todo programador Web deveria saber (exemplos em PHP, mas são válidos para qualquer linguagem com suporte a PCRE).
Validação de nomes de usuário
4 a 28 caracteres alfanuméricos e underscores:
$string = "userNaME4234432_";
if (preg_match('/^[a-z\d_]{4,28}$/i', $string)) {
echo "exemplo 1 ok.";
}
Validação de números de telefone
(##) ####-#### ou ##-####-####
$string = "(32) 5555-5555";
if (preg_match('/^(\(?[0-9]{2}\)?|[-. ]?)[ ][0-9]{4}[-. ]?[0-9]{4}$/', $string)) {
echo "exemplo 2 ok.";
}
Endereços de e-mail
foo@bar.foo
$string = "first.last@domain.co.uk";
if (preg_match('/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.]
[a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/',
$string)) {
echo "examplo 3 ok.";
}
CEPs
#####-### ou ########
$string = "55324-432";
if (preg_match('/^[0-9]{5,5}([- ]?[0-9]{4})?$/', $string)) {
echo "exemplo 4 ok.";
}
Endereços IP
255.255.255.0
$string = "255.255.255.0";
if (preg_match('^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$'
, $string)) {
echo "exemplo 5 ok.";
}
Código de cores RGB em Hexadecimal
#FFFFFF, #FFF, FFF, FFFFFF
$string = "#666666";
if (preg_match('/^#(?:(?:[a-f\d]{3}){1,2})$/i', $string)) {
echo "exemplo 6 ok.";
}
Comentários de múltiplas linhas
/* Lorem
Ipsun
dolor*/
$string = "/* commmmment */";
if (preg_match('/^[(/*)+.+(*/)]$/', $string)) {
echo "exemplo 7 ok.";
}
Datas
DD/MM/YYYY ou MM/DD/YYYY
$string = "30/01/2008";
if (preg_match('/^\d{1,2}\/\d{1,2}\/\d{4}$/', $string)) {
echo "exemplo 8 successful.";
}
Esses exemplos foram retirados do site Devolio[1] , porém algumas expressões eu alterei para ajustar aos padrões brasileiros de telefone e cep. Se por acaso fiz alguma besteira, peço que um REGEXPERT comente e corrija! E no segundo link[2] um validador de expressões regulares.
[1] 8 Practical PHP Regular Expressions – Devolio
[2] Perl Compatible Regular Expression Tester
Posted: December 12th, 2007 | Author: Felipe Ribeiro | Filed under: Uncategorized | Tags: apache, php, seo, web 2.0 | 4 Comments »
Com toda essa moda de SEO, Web 2.0 e etc, os desenvolvedores estão se interessando em melhorar o que é mostrado para o usuário até na URL, pois isso é bom para a indexação nos sistemas de busca – adiciona palavras-chave na url – e deixa mais entendível para quem usa o site.
Com mod_rewrite você faz um mapeamento de como as URLs são exibidas, e a que endereço elas realmente apontam, por exemplo:
Você tem uma parte do seu site que lista usuários por localidade e a URL pra essa página é www.exemplo.com.br/usuarios.php?pais=Brasil&estado=PB&cidade=Campina Grande, se você usa o mod_rewrite você pode fazer com que essa página seja aberta através da URL www.exemplo.com.br/usuarios/Brasil/PB/Campina Grande, que deixa bem mais elegante e melhor de ser indexado pelos sistemas de busca, que não costumam indexar páginas com muitos parâmetros passados por GET. (Normalmente também tem dificuldade em indexar documentos em diretórios num nível muito abaixo da raíz, mas isso é menos crítico).
E a mágica funciona assim:
1 – Certifique-se que o mod_rewrite está habilitado no seu Apache.
Uma maneira simples de fazer isso é com <? phpinfo(); ?> e procurando na parte que mostra os módulos do Apache.
2 – Crie um arquivo .htaccess na raíz do seu site.
3 – Escreva as regras no seu .htaccess:
RewriteEngine on
RewriteRule usuarios/(.*)/(.*)/(.*)$ usuarios.php?pais=$1&estado=$2&cidade=$3 [L]
(Idealmente a RewriteRule fica numa linha só, a quebra foi feita aí por motivos de formatação do blog)
Aí eu estou dizendo para o apache redirecionar qualquer request que vem para /usuarios/XPTO/FOO/BAR para /usuarios.php?pais=XPTO&estado=FOO&cidade=BAR, e onde eu coloquei o (.*) pode ser qualquer regex.
Você pode escrever quantas RewriteRule quiser no seu .htaccess e o Apache vai usar a que primeiro casar com a situação, então é bom estar ligado nessa ordem de precedência, pois se você colocar algo como:
RewriteRule usuarios/(.*)$ usuarios.php?pais=$1 [L]
RewriteRule usuarios/(.*)/(.*)/(.*)$ usuarios.php?pais=$1&estado=$2&cidade=$3 [L]
Vai ter problemas, pois nunca vai entrar no segundo caso, já que o (.*) significa “qualquer caracter, 0 ou mais vezes”, então a / entra nesse bolo, e vc vai ser redirecionado para usuarios.php?pais=Brasil/PB/Campina Grande. Então é bom ter cuidado para usar as Regex corretas e a ordem correta.
Vantagens de se usar mod_rewrite:
1 – Caso você não queira, não precisa expor qual tecnologia você está usando (ocultando a extensão .php, .psp, .pl, .py ou seja lá o que for);
2 – As URLs ficam mais legíveis e relevantes para usuários e search bots;
3 – Você pode fazer uma “gambiarra” para deixar informações relevantes na URL mesmo que não precise delas na sua página, por exemplo: você tem uma loja, e tudo que você precisa para abrir os detalhes de um produto é o id dele: produto.php?id=123456, mas para deixar a url mais bacana e ser indexada melhor você cria a regra:
RewriteRule produto/(.*)/(.*)$ produto.php?id=$2 [L]
e usa essa URL com: www.exemplo.com.br/produto/NOMEDOPRODUTO/ID e o sistema só pega o id ($2), daí ficaria algo como: www.exemplo.com.br/produto/Nintendo Wii/123456
Desvantagens de se usar mod_rewrite:
1 – Você precisa ter um cuidado re-dobrado quando passar strings com caracteres especiais como o &. Pois o .htaccess redireciona pra o seu script, o PHP no caso, e o PHP vai entender o & não como parte da sua string, mas como o separador de parâmetros do GET.
2 – Não sei se em sites de muito tráfego e muitas regras, isso pode interferir (mesmo que muito pouco) na performance, pelo fato do Apache precisar ler e testar todas as regex na url. (também não sei se é feito assim, mas acredito que sim)
Minha experiência com mod_rewrite foi pouca, talvez eu tenha falado bobagem, e se eu tiver, por favor, corrijam-me nos comentários!