Configuração de rotas (routes) no CodeIgniter
13 de julho de 2010, em Configurações, Passos Iniciais, por Tárcio Zemel

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).
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"; |
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:
- :num. O wildcard “:num”, utilizado para rotear somente números.
- :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!
30 comentários em "Configuração de rotas (routes) no CodeIgniter"
Robson Martins em 13 de julho de 2010
otimo post e parabens pelo blog …
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..
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!
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?! =/
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
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";
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?
Tárcio Zemel em 1 de fevereiro de 2011
Basta criar um controller…
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
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?
squiter em 30 de março de 2011
Tbm tenho a mesma duvida do Weverton…. =X
Marcelo Borges em 19 de abril de 2011
Pode explicar melhro como funcionaria isso?
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.
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!
Tárcio Zemel em 2 de agosto de 2011
Poderia ser mais específico?
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
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.
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
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! ;-)
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.
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?
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
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!
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.
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
Tárcio Zemel em 21 de novembro de 2011
Legal, fica a dica pro pessoal tomar cuidado com isso! Abs
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?
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.
- Como criar “páginas estáticas” com CodeIgniter | CodeIgniter Brasil em 20 de março de 2012


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