Todo framework MVC sério possui um mecanismo de customização de URLs (as vezes chamado de routing). Esse mecanismo permite que tenhamos URLs amigáveis – transformando /carros/ver/35 em /maserati-3200gt.html. Normalmente, isso é implementado utilizando expressões regulares que são mapeadas diretamente para a URL no formato controller/action/parâmetros, o que torna muito simples de ser implementado e configurado. Com as URLs do projeto configuradas, ao desenvolver as páginas temos de optar por colocar os links na forma controller/action/parâmetros (o que não é uma boa idéia, já que estaríamos ignorando a customização de URLs) ou na sua forma customizada (o que claramente é melhor).
Só existe um problema com essa abordagem: vamos imaginar que fosse necessário fazer um ajuste nas URLs no decorrer do desenvolvimento – ou até mesmo imediatamente antes de publicar o projeto. Por menor que seja o ajuste, teríamos de alterar todos os links do projeto (com sorte poderíamos utilizar um script em sed para convertê-las automaticamente, mas ainda sim seria preciso verificar depois se tudo está OK). Foi exatamente esse o problema que enfrentei em um dos projetos que trabalhei recentemente.
Resolver esse problema é mais simples do que parece, mas requer mudanças na forma como as URLs personalizadas são definidas. Na maioria dos frameworks, a configuração é feita dessa forma (ou alguma variação):
<?php
$routes = array(
'^/([a-zA-Z0-9\-]+)\.html$' => '/carros/ver/$1'
);
?>
Essa abordagem facilita a visualização de quais URLs apontam para onde, mas não permite que façamos o inverso. Ou seja, não conseguiríamos descobrir qual é a URL personalizada para um determinado controller/action. Para isso, vamos tentar decompor melhor essa configuração:
<?php
$routes = array(
'^/([a-zA-Z0-9\-]+)\.html$' => array(
'controller' => 'carros',
'action' => 'ver',
'params' => array( '$1' )
);
);
?>
Decompondo a URL de destino nas suas partes básicas (controller, action e parâmetros) podemos escrever um helper que percorre as configurações de URLs procurando pelo controller e action especificados:
<?php
function url_helper($c, $a, array $p) {
global $routes;
foreach ($routes as $rota => $info) {
if ($info['controller'] == $c && $info['action'] == $a) {
// achamos a rota que queríamos
// agora executamos o código para montar a URL - isso fica como exercício
break;
}
}
}
?>
Podemos ainda expandir esse helper para escolher a URL customizada de acordo com o número de parâmetros envolvidos. A idéia desse post é somente mostrar o caminho para desenvolver essa solução e não fornecer uma implementação completa. Uma outra solução seria rodar um script que modificasse os links nos templates a cada vez que a configuração de rotas fosse modificada.
