Configuração de rotas (routes) no CodeIgniter

13 de julho de 2010, em Configurações, Passos Iniciais, por

Rotas (routes) no CodeIgniter: configuração

O relacionamento padrão entre uma URL e um Controller no CodeIgniter segue a estrutura exemplo.com/classe/metodo/id/ (como mostrado no artigo sobre Controllers no CodeIgniter), mas, às vezes, é preciso “remapear” este relacionamento. No CodeIgniter, isso é feito através de routes (rotas).

Este é um guest post de Julio Bitencourt, que pode ser encontrado na internet através de:

Tomemos como exemplo a visualização de produtos em uma loja virtual. Digamos que a página para visualização dos detalhes de uma cadeira de balanço seja acessada através da URL minhaloja.com/produtos/detalhes/1/2 onde “produtos” é nosso controller; “detalhes” é a função que exibe os detalhes do produto; “1″ seja o código da categoria cadeiras; e “2″ seja o código de nossa cadeira de balanço. Esta estrutura funciona perfeitamente, mas, convenhamos, não é “elegante”.

Configuração de rotas

A configuração de rotas é feita através do arquivo /application/config/routes.php, na instalação padrão do CodeIgniter. Alguns exemplos de configuração de routes:

1
2
3
4
5
6
// "minhaloja.com/fale-conosco" vai direcionar para o controller "contato"
$route['fale-conosco'] = "contato";
 
// "minhaloja.com/fale-conosco" vai direcionar para o controller "cadastros"
// utilizando a função "novo_cliente"
$route['cadastro/clientes'] = "cadastros/novo_cliente";
Rotas são executados na ordem em que são definidas. Rotas “superiores” sempre prevalecem sobre rotas “inferiores”.

Wildcards ou Curingas

Você pode usar curingas (wildcards) para configurar rotas. Desta forma, é possível deixar as URLs mais dinâmicas. Existem 2 tipos de wildcards:

  1. :num. O wildcard “:num”, utilizado para rotear somente números.
  2. :any. O curinga “:any”, utilizado para rotear qualquer caractere.

Voltando ao exemplo anterior, que tal transformar a URL “minhaloja.com/produtos/detalhes/1/2″ em “minhaloja.com/1/2/”? Seguindo a estrutura padrão do CodeIgniter, pressupõe-se que se está chamando o controller “1″ e, dentro do controller, a função “2″, o que não existe na prática.

Para resolver o problema, vamos escrever a seguinte rota:

1
$route[':num/:num'] = "produtos/detalhes";

Dessa forma, haverá direcionamento para “produtos/detalhes” sempre que os seguimentos 1 e 2 da URL sejam numéricos.

Exemplo da função detalhes dentro do controller “produtos”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Produtos extends CI_Controller
{
    function __construct()
    {
        parent::__construct();	
    }
 
    function index()
    {
        // Função index é acessada quando não for passada nenhuma função para o controller
    }
 
    function detalhes()
    {
        echo $this->uri->segment(1); // retorna o código da categoria
        echo $this->uri->segment(2); // retorna o código do produto
    }
}

Rotas com expressões regulares

É possível utilizar expressões regulares para definir as rotas no CodeIgniter. Vamos reescrever a rota do nosso exemplo:

1
$route['(:num)/(:num)'] = "produtos/detalhes/$1/$2";

Agora, o controller fica assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Produtos extends CI_Controller
{
    function __construct()
    {
        parent::__construct();	
    }
 
    function index()
    {
        // Função index é acessada quando não for passada nenhuma função para o controller
    }
 
    function detalhes($id_categoria, $id_produto)
    {
        echo $id_categoria; // retorna o código da categoria
        echo $id_produto; // retorna o código do produto
    }
}

Rotas e SEO

A URL minhaloja.com/1/2/ ficou bem mais curta e elegante, mas não é amigável quando vamos falar de SEO. É muito melhor ter uma estrutura como:

http://minhaloja.com/cadeiras/cadeira-de-balanco/

Esta URL é “amigável” para os motores de busca e, se você tiver, por exemplo, um campo no cadastro de produtos da loja para armazenar o nome da categoria e uma “descrição de URL” (slug) do produto – como “cadeira-de-balanco” -, fica muito fácil. Essa técnica é comumente chamada de URLs amigáveis.

A regra do exemplo é:

1
$route['(:any)/(:any)'] = "produtos/detalhes/$1/$2";

O controller permanece inalterado; só é preciso buscar no banco de dados os produtos com base nos slugs de categoria e produto – caso não saiba como criar slugs, confira o artigo “URLs amigáveis (slug) à WordPress“, do blog desenvolvimento para web.

Rotas reservadas

Existem um wildcard reservado no CodeIgniter: “welcome”. Ou seja, você não poderá utilizar a seguinte rota em seus projetos:

1
$route['default_controller'] = 'welcome';

Conclusão

Rotas servem para alterar o relacionamento padrão entre uma URL e um Controller no CodeIgniter. Sabendo utilizar bem os tipos de rotas disponíveis, é possível criar estruturas incríveis, que realmente facilitam o desenvolvimento e acesso a controllers e funções – e o SEO agradece!

Com estas dicas já é possível configurar suas rotas e melhorar a navegação em seus projetos com CodeIgniter.

Espero que tenham gostado deste meu primeiro artigo no CodeIgniter Brasil e fiquem ligados para mais novidades!

35 comentários em "Configuração de rotas (routes) no CodeIgniter"

gravatar

Daniel Polito  em 13 de julho de 2010

Parabens pelo post… Eu precisei de algo assim há algum tempo e fiz uma gambiarra na classe Routes do CodeIgniter mesmo, funcionou, mas é bom saber o jeito certo de se fazer…

Abraços

gravatar

Robson Martins  em 13 de julho de 2010

otimo post e parabens pelo blog …

gravatar

Ricardo dos Santos  em 17 de julho de 2010

Mais uma vez… parabens…

Como de costume… passando aqui para ter ajuda com minhas dificuldades, já que sou novato no CI…

Mais uma vez, um post seu me ajudando…

Valeu..

gravatar

Julio Bitencourt  em 20 de julho de 2010

Daniel! Que bom que ajudou! Dê uma pesquisada em mais opções de rotear com expressões regulares. Quebram um galho!

Robson. Obrigado :)

Ricardo. Muito obrigado! Continue acompanhando o CodeIgniter Brasil, sempre teremos coisa nova por aqui!

gravatar

Vinicius  em 23 de julho de 2010

Muito legal. Mas, no caso do exemplo, se existir uma página algo como minhaloja.com/conteudo/quem_somos o route tentará localizar um detalhe de produtos, correto?! =/

gravatar

Julio Bitencourt  em 27 de julho de 2010

Exato Vinícius.

O problema de se utilizar (:any) no primeiro seguimento da URI é que todos seus controllers deixarão de funcionar.

Para contornar este problema, utilize Expressões Regulares para restringir a rota. Exemplo:

$route['^((?!conteudo|sobre|outro-controller...)\S*)'] = “produtos/detalhes/$1/$2″;

Esta também foi uma dúvida do Daniel Polito

gravatar

Julio Bitencourt  em 25 de outubro de 2010

Exatamente Vinicius. Para contornar este problema você pode listar em uma ER uma lista de exclusão. Sua regra ficaria mais ou menos assim:

$route['^((?!conteudo)S*)'] = "produtos/detalhes/$1/$2";

gravatar

eduardo_godoy  em 10 de janeiro de 2011

Pessoal, criei um site no Codeigniter e agora quero criar um blog vinculado a ele, ou seja, para ficar assim: http://www.meusite.com.br/blog. Alguém pode me dizer como posso fazer isso?

gravatar

Tárcio Zemel  em 1 de fevereiro de 2011

Basta criar um controller

gravatar

eduardo_godoy  em 1 de fevereiro de 2011

É então… só que eu pensei em colocar um blog do wordpress lá dentro… mas , ja resolvi. Era mais simples do que imaginava (coloquei a pasta do wordpress renomeada como blog na raiz do diretorio) e assim consigo acessar por site/blog

gravatar

Weverton Couto T.  em 30 de março de 2011

Desse modo, eu precisaria criar uma rota de exclusão para cada página existente?
Não há outro modo de fazer isto?

gravatar

squiter  em 30 de março de 2011

Tbm tenho a mesma duvida do Weverton…. =X

gravatar

Marcelo Borges  em 19 de abril de 2011

Pode explicar melhro como funcionaria isso?

gravatar

saulopaiva  em 8 de junho de 2011

Uma outra forma de estabelecer novas rotas é sobrescrevendo o método _remap() do controle.

http://codeigniter.com/user_guide/general/control

Essa forma é particularmente boa pra quem tem menor domínio de expressões regulares ou precisa fazer algum controle lógico durante o redirecionamento.

gravatar

Gerson  em 2 de julho de 2011

Olá, bom dia!
Desculpe, não sei se é aqui que eu posso fazer essa pergunta. Se não for, por favor, me desculpem.
É o seguinte: tenho um projeto que, quando acesso algumas funções, retorna uma linha que possui isso:
/index.php/?./
O que seria esse "/?./"?

OBS: codeigniter 2.0.2

Desde já agradeço!

gravatar

Tárcio Zemel  em 2 de agosto de 2011

Poderia ser mais específico?

gravatar

Gabriel Fernandez  em 4 de agosto de 2011

Galera,

Se eu quiser que
http://www.meusite.com/teste e http://www.meusite.com/teste/info

apontem para o mesmo controler… eu consigo fazer isso só com uma linha?

Pois a solução abaixo não funciona..

$route['teste/(:any)'] = "controller_teste";

se eu botar http://www.meusite.com/teste/parametro ele funciona mas se eu botar http://www.meusite.com/teste ele não funciona não

gravatar

Tárcio Zemel  em 5 de agosto de 2011

Da maneira que você configurou não vai funcionar, mesmo. Repare que "teste/(:any)", a expressão regular está no segundo segmento. Quando você tentar acessar "teste" ele está somente no primeiro.

Você terá que usar 2 linhas, realmente.

gravatar

Felipe  em 24 de setembro de 2011

Opa,
Cara to tomando uma peia dos routes dele, tô armazenando minhas controls em subfolders, no routes.php eu declaro o seguinte:
$route['teste/(:any)'] = "folder/controller" = *pelo que eu entendi tudo que estiver direcionando para essa pasta vai se transformar em exemplo.com/teste, correto?
Se eu adicionar mais um (:any) pra ele pegar os functions, tá correto? valeu

gravatar

Tárcio Zemel  em 26 de setembro de 2011

Na verdade, é o contrário: quando digitam o que consta na chave do $route ele joga para o valor. Dê uma lidinha com calma no artigo que você vai ver! ;-)

gravatar

Tárcio Zemel  em 6 de outubro de 2011

Se funciona no localhost e não funciona no servidor, você tem que configurar o server para que o ambiente fique igual ao seu local.

gravatar

Alan  em 1 de novembro de 2011

E ai galera!

Caso eu quisesse passar apenas um parâmetro na url e com ele verificar se existisse uma classe ou método com aquele nome e caso não existisse nem um nem outro eu faria uma busca no banco de dados com este parâmetro me retornando os dados do usuário.

Hoje no meu sistema faço o seguinte:

$route['(:any)'] = "perfil/$1";
exemplo http://educacaosolidaria.com.br/u/alanicolasouza

mas gostaria de deixar assim: http://educacaosolidaria.com.br/alanicolasouza

Alguem já fez isso?

gravatar

leandro  em 15 de novembro de 2011

Pessoal, no meu PC funciona perfeitamente minha rota: http://www.meusite.com.br/porto-alegre/acesso

Porém quando coloco no servidor não funciona….
Alguém saberia dizer o que pode ser? O servidor já esta com o mod_rewite habilitado.

Att

gravatar

Tárcio Zemel  em 17 de novembro de 2011

Faça um condicional para ver se o primeiro segmento é um usuário. Acho que, no caso, nem precisa ser com router, é algo para if/else, mesmo! ;-)

Abraços!

gravatar

Tárcio Zemel  em 17 de novembro de 2011

Apesar de você não ter falado que erro, especificamente, está acontecendo, eu arriscaria que o servidor está barrando as regras no seu .htaccess. Alguns fazem isso por medida de segurança.

gravatar

Leandro  em 18 de novembro de 2011

Pessoal, sinistro….
O problema era que no servidor online ele é casesensitive ou algo do tipo então não posso usar letras maiúsculas nos nomes dos meus controllers. EX:

LOCAL: $route['([a-z]+)/cadastro/incluirclient'] = "Cadastro/incluirclient";
SERVER: $route['([a-z]+)/cadastro/incluirclient'] = "cadastro/incluirclient";

Até mais

gravatar

Tárcio Zemel  em 21 de novembro de 2011

Legal, fica a dica pro pessoal tomar cuidado com isso! Abs

gravatar

Amilton  em 17 de abril de 2012

Amigos, sou novo no CI. Estou tentando testar o route, mas está dando erro de página não encontrada do apache (não o erro 404 personalizado do CI).
O que deve estar acontecendo?

gravatar

Tárcio Zemel  em 18 de abril de 2012

Poucas informações pra tentarmos encontrar uma solução. Conte mais a respeito, forneça alguns detalhes.

gravatar

Lineker  em 4 de janeiro de 2013

Amigos estou com um sistema de agregador de conteudos onde quando chamo uma rota aparece o seguinte erro The requested URL /agregador/contato/ was not found on this server.
Como corrijo?

Exemplo meu projeto esta assim
C:wampwwwagregadorapplicationcontrollers
dentro de controllers tenho meu arquivo contato.php

como chamo essa pagina na rota?

gravatar

Tárcio Zemel  em 5 de janeiro de 2013

Você consegue acessar esse controller desabilitando todas as rotas? Se sim, é problema com alguma que você configurou errado; se não, é problema com a própria definição da estrutura/controllers do projeto.

gravatar

José Ivan  em 19 de julho de 2013

Como eu faço pra criar rotas específicas para cada registro de uma tabela, exemplo:
Eu tenho um controller motos que tem o método listar que recebe o id da moto, a url é +- assim:
motos/listar/<id_da_moto>

Eu quero que a rota motos/<categoria_moto>/<nome_da_moto> aponte para moto/listar/<id_da_moto>… como faço isso? preciso gerar o route a partir de dados do db, mas como faço isso?

gravatar

Rafael  em 14 de maio de 2014

Também estou com este problema, acabei de colocar o CI no xampo, e criei minha primeira rota, mas ela não funciona, vai direto para pagina de erro do apache, não é o CI que responde.

gravatar

vernonlacerda  em 16 de dezembro de 2015

eu poderia usar as rotas para configurar uma pasta config em outro lugar que não na application?

Valeu.

Comente!