Back-End

8 jun, 2009

Otimizando URLs na hora de migrar um site em PHP para CakePHP

Publicidade

Olá pessoal,

outro dia fui chamado para fazer um refactory de um dos primeiros sites que desenvolvi. Na época eu não me preocupava com URLs amigáveis nem coisa semelhante. Para ser sincero, nem sabia do que se tratava.

O site havia sido desenvolvido inteiramente usando chamadas diretas para os scripts PHP, como por exemplo: noticias_ler.php?id=id_da_noticia.

Como uma das características que seriam agregadas a nova versão do site seria a otimização e uso de URL amigáveis, eu não poderia deixar do jeito que estava. Aliás, eu usaria o CakePHP no projeto, então, sem chances de manter como estava.

A primeira coisa eu me veio a cabeça foi mudar pra CakePHP. Não pensei nas consequências disso. Refletindo um pouco mais, vi que uma mudança radical em todas as URLs do site poderia não ser uma coisa bacana, já que o mesmo já contava com mais de 40 mil notícias, dentre outros conteúdos. Já que todos os links antigos deixariam de funcionar, isso não seria uma boa para motores de busca, nem mesmo para quem colocou uma determinada notícia no favoritos, por exemplo.

Logo, imaginei que eu teria que redirecionar todas as URLs (pelo menos as mais importantes) para o novo formato. Mas eu queria redirecionar algo como: noticia_ler.php?id=10 para /noticias/ler/10/titulo-da-noticia-bonito.

A primeira coisa que fiz foi rotear no routes.php a URL noticia_ler.php para um controller qualquer (ou para o controller Noticias). No exemplo a seguir, redirecionei para o controler redireciona.

PHP:
Router::connect('/noticia_ler.php*', array('controller' => 'redireciona', 'action' => 'noticia'));

O controller Redireciona, na verdade, não precisaria nem existir. Poderia ter feito dentro do próprio noticias. Mas a minha idéia era controlar todos os redirects de um único controller.

Na action noticia do controller Redireciona:

PHP:

         $id = $this->params["url"]["id"];

         $n = $this->Noticia->findById($id);

         $slug = Inflector::slug($n["Noticia"]["titulo"]); // retira acentos e etc

         $slug = strtolower($slug); // passa pra minusculo

         $slug = str_replace("_", "-", $slug); // troca _ por -

         $this->redirect("/noticias/ler/".$id."/".$slug, 301, true);

Detalhe do uso do método slug da classe Inflector, que retira todos os caracteres especiais e espaços para a construção de URLs amigáveis, transformando, por exemplo, “Tulio Faria” em “Tulio_Faria”. Em seguida faço algumas transformações para ficar no formato que gosto: “tulio-faria”, tudo minúsculo e separado por hífen.

O segundo paramêtro do redirect é o código de redirecionamento a ser usado, no caso do 301 é Movido Permanentemente. O terceiro paramêtro indica que será dado um exit() após o redirecionamento.

Bom pessoal, é isso!

Espero que isso ajude-os assim como me ajudou! Qualquer dúvida, comentem!

Forte abraço!