Url Rewriting – como tornar a estrutura de urls do seu site amigável e profissional

Há algumas semanas, um grande buzz foi gerado no Twitter depois que uma reportagem sobre fraudes na internet deu a entender que urls com a extensão .php seriam, em sua maioria, vírus. O “especialista em segurança” estava dando dicas para que as pessoas não clicassem em links suspeitos, e a forma que ele falou, com a edição que foi feita, deixou bem claro que “a maioria das páginas em php são vírus.” O acontecido se deu no Jornal Hoje, e o vídeo pode ser visto nesse link: http://www.youtube.com/watch?v=x9_qwgYrESg .

O que muitas pessoas podem não saber é que a linguagem PHP é a mais utilizada na WEB nos dias atuais. Pesquisas recentes indicam que ele é usado em 59% dos sites (contra 34% do ASP, que fica em segundo). Acontece que nem todo site que usa php precisa mostrar isso através das extensões .php. Existem técnicas para esconder a extensão dos arquivos; essas técnicas são geralmente usadas por questões de segurança e otimização para mecanismos de busca. Sites e CMSs profissionais (como o WordPress, usado aqui neste blog) não exibem suas extensões de arquivo, e a técnica mais utilizada para isso é Url Rewriting.

Para quem não conhece, a técnica de Url Rewriting funciona como uma reescrita de urls, um tipo de mascaramento que tem por objetivo tornar a url mais amigável e esconder as extensões dos arquivos, o que acaba tendo um aspecto de segurança também. Os servidores web e frameworks mais conhecidos implementam esse mecanismo, seja de maneira nativa ou através de módulos. No nosso caso, como estamos falando de PHP, estamos falando de Apache com mod_rewrite habilitado (a maioria dos servidores pagos e instalações padrão já vêm com esse módulo ativo).

Nesse post, você terá uma visão geral de como criar as regras do url rewriting em uma estrutura de site que utiliza essa técnica de maneira prática e inteligente, similar ao que é utilizado pelo WordPress.

mod_rewrite e o .htaccess

Antes de mais nada, é legal entender como funciona o esquema de url rewriting no apache. Precisamos estabelecer regras que devem ser colocadas no arquivo .htaccess, na raiz do diretório www (o arquivo .htaccess também pode vir em qualquer subdiretório, estabelecendo regras próprias para aquele diretório específico). As regras são definidas através de expressões regulares. A imagem abaixo explica como é feito o processamento após a requisição vinda do usuário:

 

a requisição

 

Vamos supor que temos o diretório www como a raiz do site meusite.com . Imagine que dentro dessa pasta www, nós temos o diretório “abc/def/ghi” (acessando via http, a url ficaria http://meusite.com/abc/def/ghi ). Mas gostaríamos que todos os arquivos dessa pasta fossem acessíveis através de um caminho diferente e mais simples: /xyz . Ou seja, ao invés de acessar pelo endereço http:/meusite.com/abc/def/ghi/arquivo.html, eu quero usar http://meusite.com/xyz/arquivo.html (onde o diretório /xyz na verdade não existe).

Nosso arquivo .htaccess ficaria assim:

RewriteEngine On

RewriteBase   /

RewriteRule  ^/xyz(.*) /abc/def/ghi$1

Para maiores detalhes sobre todas as regras possíveis, e o que cada item significa, é bom dar uma olhada na documentação do Apache sobre o mod_rewrite:  http://httpd.apache.org/docs/current/mod/mod_rewrite.html . Esse post aqui também tem umas dicas básicas muito boas: http://php.refulz.com/201105/url-rewriting-with-apache/ (ambos em inglês).

Passo 1 – .htaccess

Podemos criar várias regras no htaccess para nossos scripts, porém, existe uma maneira mais simples de trabalharmos com o url rewriting. Através de uma regra geral, podemos deixar o processamento a cargo de um script php, ao invés de encher o arquivo .htaccess de regras. Esse é o esquema utilizado pelo WordPress. Abaixo está o conteúdo de um arquivo .htaccess padrão utilizado por essa plataforma:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Basicamente, o que esse .htaccess especifica é que: toda requisição, tendo como diretório base o “/”, que não for um arquivo nem um diretório (que jogariam um erro 404 normalmente, pois não existem), deve ser repassada para o script /index.php, que ficará responsável por tratar essas requisições da maneira que quiser. Ou seja, no arquivo index.php deve haver um processamento para obter a requisição feita e decidir o que deve ser chamado – um típico controlador.

É bom lembrar que diretórios existentes não serão afetados, já que a regra do url rewriting só irá redirecionar para o index quando não existir um arquivo ou diretório no caminho especificado.

Passo 2 – Controlador php e estrutura de diretórios

Utilizando o .htaccess exemplificado acima, o script index.php será responsável por definir o que deve ser chamado – faremos isso com uso de includes. Fica a seu critério a organização do seu framework, porém irei fazer aqui uma sugestão, que deixa o diretório de arquivos bem organizado e torna o desenvolvimento bem mais fácil. Primeiro, vamos dar uma olhada no arquivo index.php, que é o controlador do framework:

<?php
/* no config.php você pode iniciar sessão e conectar ao BD por exemplo */
require_once("includes/config.php");

$uri = $_SERVER['REQUEST_URI'];
//default = index
$pagina = "index";

if($uri != "/")
{
      /* faz o parsing do url rewriting */

        /* retira parametros de url*/
	$t = explode('?',$uri);
	$path = explode("/",$t[0]);

	$module = strtolower($path[1]);
	/* checagem extra para a existência de um diretório com esse nome */
	if(!is_dir($module))
	{
          /*verifica se existe o módulo requisitado*/
		if(is_dir("modules/$module"))
			$pagina = $module."/index";
		else if(is_file("modules/$module.php"))
			$pagina = $module;
		else
            /* caso não exista, incluir o módulo de 'not found' */
			$pagina = "404";

	}
}

require_once("modules/$pagina.php");

Como vocês podem ver, a lógica é bem simples. É importante verificar se o arquivo existe antes de tentar incluí-lo – verificamos se existe aquele “módulo”. Uma requisição feita para “/contato“, por exemplo, resultará na checagem/inclusão do arquivo “modules/contato/index.php” OU “modules/contato.php“.

E assim, para cada página que você quiser acrescentar, pode criar um arquivo ou diretório dentro da pasta “modules” (você poderia usar diretórios para organizar melhor quando houvesse “submódulos”). Dentro desse arquivo você ainda pode criar regras (um switch já serve) para testar um segundo,  terceiro nível de requisição (por exemplo: “/contato/orcamento” ). Nesse caso, a página que será incluída continuará sendo a “contato.php“, dentro dela é que você irá checar se existe um “submódulo”, o que pode ser feito facilmente com regex ou verificando o array $path. Nossa estrutura de diretórios/arquivos estaria mais ou menos assim:

/
/includes
   /includes/config.php
/modules
   /contato.php
   /404.php
/.htaccess
/index.php

Bom, acredito que a partir daí já dá pra desenvolver a idéia né? Adicionando a engine de templates Smarty, você já deixa seu framework mais elaborado e modulado, facilitando ainda mais a criação de novas páginas / módulos. Nesse caso, use os arquivos de módulo para obter as informações necessárias, e dar o display no template.

É importante ter um módulo “404″ para chamar quando não encontrar a página que o usuário pediu, já que não haverá mais o erro 404 padrão pois estamos pegando tudo o que “não existe” e tentando mapear no nosso framework. Nesse arquivo você deve exibir alguma mensagem indicando que o conteúdo não foi encontrado.

, , ,

No comments yet.

Deixe um Comentário