No seguimento deste post, relembro o exemplo que dei do jornal Público: http://www.publico.clix.pt/Sociedade/divulgacao-de-escutas-na-internet-punivel-pela-lei-do-cibercrime_1419063. Acho que é claro para todos que não existe, no site do jornal Público, nenhum directório “Sociedade” e muito menos um directório para cada notícia que eles colocam.

Na realidade, o que acontece é um redireccionamento invisível do pedido para um script central que, neste caso, trata das notícias. Esse redireccionamento é feito com a extensão mod_rewrite do Apache. O mod_rewrite é uma espécie de pau para toda a obra dos redireccionamentos, desde visíveis a invisíveis, com inúmeras aplicações.

Por exemplo, uma das aplicações mais simples serve para redireccionar, de forma visível, de um domínio para outro. Aqui no DreamsInCode, por exemplo, é possível aceder ao site por http://www.dreamsincode.com, assim como por http://dreamsincode.com. Por várias razões, eu quero forçar que a entrada seja sempre pelo domínio completo, com www. Esse objectivo é conseguido colocando o seguinte código num ficheiro .htaccess na raíz do site:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{HTTP_HOST} ^dreamsincode\.com$ [NC]
RewriteRule ^(.*)$ http://www.dreamsincode.com/$1 [R=301,L]
</IfModule>

As instruções IfModule servem para verificar se o módulo foi compilado com o Apache. Na falta destas instruções e no caso da extensão não estar carregada, o mais provável seria ficarem a olhar para uma página de erro, 500 Internal Server Error. Depois de se ligar a extensão, via RewriteEngine On, vêm as condições com RewriteCond: em primeiro lugar aquilo que queremos comparar, neste caso HTTP_HOST, uma expressão regular e finalmente um conjunto de modificadores. O modificador que estou a usar neste exemplo é o NC, que indica que a comparação deve ser feita ignorando a capitalização.

Finalmente, temos a regra de redireccionamento, RewriteRule: primeiro apanhamos, com uma expressão regular, tudo o que está no endereço para além do domínio e depois dizemos exactamente como queremos reescrever o caminho – o $1 indica que é para colocar tudo o que apanhamos antes a seguir ao novo domínio. O modificador R indica que é um redireccionamento visível, com o respectivo código a devolver ao browser (neste caso, 301 Moved Permanently) e o L indica que é a última regra deste bloco.

Voltando ao nosso problema inicial, o que nós queremos não é um redireccionamento visível, mas sim invisível. Uma possível solução para o caso do Público seria a seguinte:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteRule ^([a-z0-9-]+)/?$ index.php?action=getNoticiasCategoria&nome_categoria=$1
RewriteRule ^([a-z0-9-]+)/([a-z0-9-]+)/?$ index.php?action=getNoticia&nome_categoria=$1&nome_noticia=$2 [L]
</IfModule>

Reparem como não existem condições, isto é, tudo o que vier por aqui no formato correcto é automaticamente apanhado. As expressões regulares ditam que é para apanhar qualquer coisa que contenha letras, números e hífens. A primeira regra é executada se vier apenas um directório no URL (por exemplo, http://www.publico.clix.pt/Sociedade/) e a segunda se vierem dois, que é o nosso exemplo inicial. O pedido é então reencaminhado para um script, com parâmetros diferentes, que devolve o que é necessário de forma opaca para o browser, que continua a mostrar o endereço pedido – reparem como nenhuma das regras tem o modificador R.

Para finalizar, enquanto escrevia estes dois posts encontrei uma cheat sheet (uma folha de copianço) para o mod_rewrite muito boa. Aliás, existem várias cheat sheets para diversas coisas nesse site, assim como vários artigos interessantes.


Actualização 2017: Enviaram-me esta cheat sheet um pouco mais profunda.

Partilhar no Sapo Links Partilhar no del.icio.us Partilhar no Digg Partilhar no Twitter Partilhar no StumbleUpon Partilhar no MySpace Partilhar no Facebook

Comentários Deixar um comentário

 Categorias
 Arquivo
 Projectos em Destaque
 Últimas Postas no Blog
 Últimos Comentários do Blog