URLs no CodeIgniter

21 de janeiro de 2010, em Passos Iniciais, por

No artigo sobre MVC foi visto que, no CodeIgniter, os controllers são responsáveis por controlar todo o fluxo do software; a lógica da coisa; as regras de negócio do sistema. Por padrão, as URLs no CodeIgniter são feitas para serem URLs amigáveis (Friendly URLs),quer dizer, são apresentadas em uma estrutura propícia para as páginas do site/sistema serem melhor indexadas por mecanismos de busca, tais como o Google. Em outras palavras, as URLs no CodeIgniter são baseadas em segmentos.

Estrutura de URL no CodeIgniter

Vamos tomar por exemplo o seguinte endereço, gerado a partir de um sistema fictício, feito em CodeIgniter:

http://www.site.com.br/noticias/artigos/meu_artigo

Como podemos ver, trata-se de um URI normal, que pode ser encontrado em milhares de sites por aí. Então, dentro do CodeIgniter, isso é interpretado da seguinte maneira:

http://www.site.com.br/classe/funcao/id

E, dentro dessa estrutura de URL, o significado de cada segmento:

  1. classe. O primeiro segmento, “noticias”, representa o controller (classe) “noticias”.
  2. funcao. O segundo segmento, “artigos”, é uma função (funcao) que existe no controller “noticias”.
  3. id. O terceiro, “meu_artigo”, é o parâmetro (id) da função “artigos” do controller “noticias”.

Quer dizer, existe um controller “noticias” que possui uma função “artigos” (função esta que recebe um parâmetro, “id”, para funcionar):

class Noticias extends Controller
{
    function artigos($id)
    {
        // código da função
    }
}

Não se preocupe com essa estrutura, ela será melhor detalhada no artigo sobre Controllers.

Vamos supor que precisássemos de uma função com 2 parâmetros. O CodeIgniter entende, também:

class Matematica extends Controller
{
    function soma($x, $y)
    {
        echo $x + $y;
    }
}

Um belo “10″ será mostrado na tela para quem acessar o URI:

http://www.site.com.br/matematica/soma/5/5

Removendo o segmento “index.php”

Em uma instalação do CodeIgniter padrão, o segmento “index.php” será sempre mostrado (isso devido a “questões internas”, digamos assim). Mas, caso se queira, é possível retirar do URL. Para tal, temos que nos valer de algumas poucas instruções em um arquivo .htaccess:

RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

O código mostrado faz com que qualquer solicitação HTTP que não sejam para “index.php”, imagens e “robots.txt” é tratada como uma solicitação para o arquivo index.php (mesmo “index.php” não aparecendo na URI).

Em função de configurações de servidor, algumas vezes o .htaccess mostrado pode não funcionar. Caso isso aconteça com você, dê uma olhada nesse tópico do fórum oficial sobre problemas de htaccess no CodeIgniter.

Adicionando sufixo ao URL

É possível brincar um pouco mais com as URIs no CodeIgniter. Um dos recursos interessantes é acrescentar um sufixo no URI, “dando a impressão” de que se está acessando um arquivo.

Veja no arquivo de configuração do CodeIgniter (/system/application/config/config.php) a seção “URL suffix”. É lá que você vai alterar a variável $config['url_suffix'] e inserir o que você quer que seja seu sufixo. Por exemplo, você pode ter URIs como:

http://www.site.com.br/noticias/artigos/meu_artigo.html

Trabalhando com Query Strings

Como foi visto, por padrão, o CodeIgniter apresenta uma estrutura de URLs amigáveis. Mas o framework possui tanta flexibilidade e opções de configuração e uso que é possível trabalhar com query strings. Isso, mesmo! Se você quer reviver a “tradição” na internet e fazer com que seu sistema pareça ter sido feito há 10 anos atrás, é possível apresentar query strings!

Para isso, você deve ir ao arquivo de configuração citado (config.php) e, na seção “Enable Query Strings”, alterar a diretiva $config['enable_query_strings'] para “TRUE”, ficando dessa maneira:

$config['enable_query_strings'] = TRUE;
$config['controller_trigger'] = 'c';
$config['function_trigger'] = 'm';

Percebam as 2 outras diretivas. É possível configurar os “triggers” que representam, respectivamente, o controller e a função que se deseja usar. Dando um exemplo de como ficaria um URI usando as query strings (e os triggers default do CodeIgniter), teríamos algo como:

index.php?c=estatisticas&m=mostrar

Quer dizer, será executado o código da função “mostrar” do controller “estatisticas”. Nostálgico…

Ao optar pelo uso de query strings, você está abrindo mão de diversas vantagens nativas do CodeIgniter, não podendo utilizar alguns helpers importantes de URL.

Conclusão sobre URLs no CodeIgniter

É gritante a facilidade com a qual se trabalha com URLs no CodeIgniter! Através de uma estrutura baseada em segmentos, os endereços gerados são fáceis para uma melhor indexação do site/sistema por mecanismos de busca, ao mesmo tempo em que oferece uma capacidade incrível para se trabalhar com as funções (nativas e criadas) do framework.

A flexibilidade é tamanha que é até possível mexer com query strings – mesmo que, para isso, tenhamos que abrir mão de alguns recursos nativos muito úteis.

Com certeza o CodeIgniter, provando mais uma vez que é o melhor framework PHP, mostrou que um dos pilares de seu poder de funcionamento é sua estrutura de URLs!

33 comentários em "URLs no CodeIgniter"

gravatar

Vítor Avelino  em 21 de janeiro de 2010

Apesar da baixa atividade aqui, os posts são sempre simples, objetivos e de grande utilidade.

Continuem assim!

[]’s

gravatar

Ubiratan  em 24 de janeiro de 2010

Muito bom seu artigo, gosto muito deste framework e utilizo há anos, Se você precisar de ajuda com artigos (para aumentar a frequencia de posts ) pode contar comigo ok ?

Abraços.

gravatar

Tárcio Zemel  em 25 de janeiro de 2010

@ Vitor Avelino,

@ Ubiratan

É, realmente a frequencia dos artigos não é das melhores, algo que pretendemos resolver para melhorar a qualidade do blog.

Temos a ideia de, futuramente, abrir espaço para artigos dos leitores. Peguei seu contato, Ubiratan! ;-)

Obrigado por comentarem!

gravatar

Herton Vilarim  em 9 de fevereiro de 2010

Muito show! Parabens! ótimos artigos!

gravatar

Bruce  em 19 de maio de 2010

Apesar da baixa atividade aqui, os posts são sempre simples, objetivos e de grande utilidade.

Continuem assim!

[]’s

gravatar

Tárcio Zemel  em 20 de maio de 2010

@ Herton Vilarim
Nós é que agradecemos a visita e a participação! Abraços!

@ Bruce
Pois é, Bruce, a ideia é melhorar a frequência de publicação, mas, por enquanto, estamos na faixa de +/- 2 por mês… Contamos com sua ajuda! ;-)

gravatar

Hugo Fittipaldi  em 6 de setembro de 2010

Excelente artigo. Agora, tenho uma dúvida: como faço para retirar um determinado 1o segmento da url.
Explico: na minha classe principal tenho três itens, o index, o faleconosco e videos. Em outra classe, projetos, tenho casas, apartamentos e assim por diante; de forma que no site ficaria assim:
meusite.com.br/index.php/principal/
meusite.com.br/index.php/principal/faleconosco.php
meusite.com.br/index.php/principal/videos.php
meusite.com.br/index.php/projetos/casas.php
meusite.com.br/index.php/projetos/apartamentos.php
O index.php eu consegui retirar tranquilamente pelo htaccess, mas como faço para retirar o "principal" de forma que as urls fiquem assim:
meusite.com.br/
meusite.com.br/faleconosco.php
meusite.com.br/videos.php
meusite.com.br/projetos/casas.php
meusite.com.br/projetos/apartamentos.php

Obrigado.

gravatar

Igor rosa  em 9 de dezembro de 2010

Tenho uma dúvida!
Quando eu habilito para usar prefixos por exemplo .html e vou acessar uma função em algum controller qualquer dá página inexistente.
Adicionei o sufixo lah no config e dá esse erro. Pq?

gravatar

Igor rosa  em 9 de dezembro de 2010

perdão.. é sufixo e não perfixo! :D

gravatar

Tárcio Zemel  em 1 de fevereiro de 2011

Pra fazer isso, você terá que usar configuração de rotas (routes) no CodeIgniter.

gravatar

Tárcio Zemel  em 1 de fevereiro de 2011

Poderia dar uma exemplo?

gravatar

Raphael Figa  em 15 de abril de 2011

Olá,

Conheci o blog hoje, fui pela categoria Passos Iniciais, e estou lendo todos os artigos que vem pela frente, neste ponto surgiu uma duvida.

Estou desenvolvendo um sistema de serviços locais.
E havia definido no projeto que as urls serão da seguinte forma
http://www.site.com.br/ http://www.site.com.br/estado/ http://www.site.com.br/estado/cidade/ http://www.site.com.br/estado/cidade/bairro/

Agora a duvida é a seguinte.
Vamos supor estas duas URLS
http://www.site.com.br/sp/ http://www.site.com.br/rj/

Ambas tratam do estado e pelo meu projeto um único script iria preparar o conteúdo para ser apresentado.

A duvida ridícula é a seguinte:

Teria que ter duas classes idênticas para fazer a mesma função?

Agradeço a atenção

E se possível aguardo uma resposta de vocês que possuem um conhecimento muito maior que o meu.

Obrigado

gravatar

Tárcio Zemel  em 16 de maio de 2011

Não precisa, Raphael. Você pode ter uma única função de pegar os arquivos do BD e usar a sigla do estado como parâmetro.

Dê uma olhadinha na documentação da URI Class. A primeira função mostrada vai lhe ser muito útil.

Abraços!

gravatar

Victor  em 12 de julho de 2011

Continue o bom trabalho amigo! Você vai longe

gravatar

Tárcio Zemel  em 2 de agosto de 2011

Obrigado, Victor! Conto com sua presença nos próximos artigos!

gravatar

Silas Vasconcelos  em 26 de janeiro de 2012

Muito bom mesmo, estou iniciando com frameworks e decidie começar pelo CodeIgniter e concertesa vie que não escolhie mal, parabems pelo artigo que esta nota 10.

gravatar

Neto  em 5 de fevereiro de 2012

Tenho um site onde utilizo a seguinte url para chamar determinada página: http://www.meusite.com.br/encontre-isto-aqui-na-base onde o que vem depois da barra é o que será buscado no BD. É possível usar essa estrutura com o CI. Pelo que vi ele precisa de uma classe depois da barra, mas na minha estrutura seria um ID, é possível isso?

gravatar

Tárcio Zemel  em 10 de fevereiro de 2012

Oi, Neto!

É possível, sim. Dê uma olhada no artigo "Configuração de rotas (routes) no CodeIgniter".

Abraços!

gravatar

Fabiano  em 24 de março de 2013

Colega Tárcio, por favor gostaria da sua ajuda:

Eu tentei de tudo, mas eu não consigo remover o segmento index.php e fazer outros controllers serem acessados sem o /index.php/etc …

Eu ja fiz o seguinte:
- habilitar mod_rewrite no httpd.conf;
- deixei $config['index_page'] = '';
- coloquei certo a path $config['base_url'] = 'http://localhost/news/';
- criei um arquivo .htaccess no diretorio news, e coloquei as instruções que voce postou nesse artigo.

Mas mesmo assim não consigo de jeito nenhum… Sempre da o erro de "Not Found".

Gostaria de ajuda se possivel, obrigado !

gravatar

Tárcio Zemel  em 26 de março de 2013

Primeiramente: estava tudo funcionando antes de você fazer isso? De repente pode ser alguma configuração do seu server.

Se sim, você tentou acessar o URL correto do seu controller/método?

Se sim, também, coloca seu código num pastebin da vida pra gente dar uma olhada. :-)

gravatar

Fabiano  em 29 de março de 2013

Obrigado por tentar me ajudar Tárcio!

Então, eu consegui arrumar o problema: descobri que era a bendita da configuração no apache(arquivo httpd) !

Por algum motivo meu Apache não possuía AllowOverride All pré setado, na parte das configurações do meu diretório raiz. Como eu não tinha muitos conhecimentos em mexer na engine do apache, isso me passou totalmente despercebido!

Para quem não sabe, se você não possuir o AllowOverride All setado na configuração do seu diretório no arquivo httpd, ele irá ignorar qualquer arquivo .htaccess que existir dentro do seu projeto, consequentemente essa dica que o Tárcio forneceu para nós para tirar o index.php não vai funcionar.

Espero que essa dica ajude alguem que também não esteja resolvendo de jeito nenhum esse probleminha chato ! Se você não conseguiu remover o index.php mesmo com a configuração perfeita nos arquivos do codeigniter, com 99% de certeza deve ser configuração relacionada ao apache !

Abraços, e obrigado pelo blog, está muito bom !

gravatar

Tárcio Zemel  em 29 de março de 2013

Opa, obrigado por relatar seu caso, Fabiano! Certamente vai ajudar mais pessoas!

Abraços!

gravatar

Rogério  em 16 de outubro de 2013

Preciso (quero, na verdade) urls na forma http://www.meusite.com/pagina/categoria/titulo/id
Como 'categoria' será dinamica, como posso implementar isso? Seria como se não tivesse a 'action'.
Sendo só http://www.meusite.com/pagina/categoria/ onde listaria os posts de uma determinada categoria funciona com
class Pagina extends Controller
{
function index()
{
//Código, lógica
}
}

Mas ao passar o titulo e o id (num view do artigo/pagina/texto completo dá erros).
Alguma dica de como fazer? Sei que parece fácil, mas meus testes foram infrutíferos..

gravatar

ltpassos  em 8 de novembro de 2013

Rogério, estou passando por um problema parecido com o seu.
O que quero é o seguinte:
Tenho o meu controller "Noticias" http://localhost/site/noticias onde é exibido as últimas noticias.

Porém ao clicar em uma noticias eu gostaria que a url gerada fosse:
http://localhost/site/noticias/34 onde 34 é o id da noticia.
Isso não funciona. Para funcionar tenho que criar a url da seguinte forma:
http://localhost/site/noticias/index/34.

A pergunta é: como faço para acabar com o "index" na url?
[]s Léo

gravatar

php  em 1 de julho de 2014

morte aos frameworks, por que não evoluir a linguagem php???

gravatar

Lucas  em 16 de dezembro de 2014

Excelente dica, eu estava procurando por isso!!!

gravatar

Thallys  em 17 de junho de 2015

Existe uma função para isso

$variavel = $this->uri->segment(3);
Neste cado ele vai pegar o terceiro segmento.
Ex: usuario/login/3
A variável vai ficar "3"

gravatar

Leo  em 25 de junho de 2015

Como faria para exibir urls neste formato: /exemplo.html

gravatar

Diogo  em 11 de agosto de 2015

Meu prezado vejo que nao sabe do que fala os frameworks forca voce a trabalhar de forma correta usando OO e outras tecnica de desenvolvimento

Comente!