Hi! Do you wanna see the English version?

Blog

URLs amigáveis com mod_rewrite

Quinta-feira, 26 de Abril, 2007 | 43 comentários

Mais uma dica rápida da série dia-a-dia de um desenvolvedor Web. Agora se tratando de um módulo do Apache: mod_rewrite.

A idéia da dica, é fornecer uma regra simples sem níveis de seção na URL.

O que é mod_rewrite?

É um módulo escrito para o servidor Apache, responsável pela reescrita de URLs em páginas Web.

Hoje em dia, com a popularização de assuntos como SEO, usabilidade e acessibilidade, esta prática se tornou comum e está cada vez mais sendo utilizada por grande portais.

Antes de mais nada, para que o módulo mod_rewrite funcione, obviamente você deve ter configurado e ativado no seu servidor Apache.

Criando o .htaccess

Crie um arquivo com o nome ".htaccess" (exatamente desta forma), e mova para a pasta raiz do seu domínio (ou onde queira implantar a reescrita). Em seguida, insira o código abaixo:

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?cod=$1

Entendendo o código:

RewriteEngine On
Ativa o suporte à reescrita
RewriteCond %{SCRIPT_FILENAME} !-f
Não aplica a condição para arquivos
RewriteCond %{SCRIPT_FILENAME} !-d
Não aplica a condição para diretórios
RewriteRule ^(.*)$ index.php?cod=$1
Regra de reescrita onde qualquer string (.*) após a pasta, onde estiver o .htaccess, será interpretado por index.php passado na variável cod

Na prática, se você tem uma URL do tipo www.url.com.br/secao/subsecao/, será interpretada por www.url.com.br/index.php?cod=secao/subsecao/. E mais, você não terá limite de níveis para utilizar com as /.

Interpretando com PHP

Com seu arquivo de reescrita criado, você já pode criar uma lógica no seu arquivo PHP para que interprete e leia as URLs passadas.

Veja um exemplo auto-explicativo:

<?php
/*
 * separa a URL por "/" e insere num vetor (array)
 */
$url = explode('/', $_GET['cod']);


/*
 * imprime a string passada após a primeira /
 * no exemplo acima, seria: secao
 */
echo $url[0];

/*
 * imprime a string passada após a segunda /
 * no exemplo acima, seria: subsecao
 */
echo $url[1];
?>

Desta forma, você pode utilizar includes para suas seções, ou qualquer outro tipo de inclusão, uma vez que você já tem suas seções separadas.

Para quem quer ler mais sobre o assunto, recomendo a documentação do mod_rewrite. O Bruno também escreveu mais detalhadamente aqui e aqui.

Até a próxima dica da série dia-a-dia de um desenvolvedor Web...

43 comentários:

Rafael Marin disse:

Eu também já escrevi sobre URLs amigáveis lá no blog. O Wordpress usa algo parecido com o que tu colocaste aí, né?

Abraços  :-D

brunnolou disse:

Sem dúvida utilizar isso hoje em dia tem se tornado indispensável.

No meu site explico como configurar e ativadar o mod_rewrite no Apache.

http://www.brunnolou.com/blog/activar-mod_rewrite-no-ubuntu/

Israel Cefrin disse:

Ciro
Muito boa a explicação. Deu para entender muito fácil como usar o mod_rewrite (que muita gente até usa, mas não sabe como nem porquê.)
Realmente o wordpress usa essa \\\'tecnologia\\\', mas ele não explica em miúdos como faz isso, apenas manda renomear o htaccess.txt.
 :-)
[]´s

Maicon Junches disse:

Muito boa essa forma, valeu ai Ciro!

RInaldi Fonseca disse:

Olá Ciro,, parabéns pelo artigo, realmente as URL amigaveis ajudam muito no indexamento dos Sites juntos ao sites de buscas.

Att
Rinaldi Fonseca
www.grifemidia.com.br

Túlio Vargas disse:

Poxa, até que enfim um ótimo tutorial sobre URL Amigaveis !!
Muito bom mesmo Ciro !
Congratulation

[]´s

André de Castro Zorzo disse:

Ciro, legal o post, e apenas para complementar, as vezes é necessário configurar o apache para que ele entenda o .htaccess (em algumas instalações isso não está ativo por padrão), fazendo a seguinte configuração:

<code>Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all</code>

Carlos La Vega disse:

explode? ensinando pela forma noob é foda...

Rodrigo Maia disse:

Realmente ajuda muito no SEO.
A um tempo atrás fiz um vídeo tutorial sobre o assunto, pra quem quiser ver, tá ai o link:
http://videotutoriais.blogspot.com/2007/08/url-aucarada-com-o-modrewrite-do-apache.html

Abraços

Fillipe disse:

Olá Ciro,
muito bom.. agora só queria saber uma coisa:
Eu consigo usar esse mod para qualquer url ? Seria só tratá-la ?
Por exemplom, se eu tiver a seguinte url:
site.com/index.php?ir=teste&cat=noticia&id=id
ficaria
site.com/noticia/id

Pelo seu código é possível fazer isso ou teria que concatenar e especificar as sub-seções?

Vlw
abraços

CACA[COBRA] disse:

Eu tambem tenha a duvida acima

Ciro Feitosa disse:

@ Fillipe:

Conforme descrito neste artigo, qualquer string após o domínio será convertido em vetor no PHP, sendo "quebrados" após as barras "/".

Assim, se você tem a URL do tipo www.site.com.br/<b>noticia</b>/<b>id</b>, o script retornaria para você, o equivalente a:

$url[0] = '<b>noticia</b>';
$url[1] = '<b>id</b>';

Daí, basta realizar as suas críticas baseado nesses resultados ($url[0], $url[1]...).

Espero que tenha assimilado.

Abraço!

CACA[COBRA] disse:

Boa Ciro...fiz um teste e já aprovei  :D

Vilson Carlos disse:

Ciro, me diga tentei fazaer e deu certo mas as imagens somem, o que acontece será ?

Ivan Gorski disse:

Muito bom  ;) Parabéns.

Leonardo Filipe disse:

meu site fica dentro de /site

consegui fazer tudo certo mas as imagens, css e js quando ficam /ajuda/10/titulo
nao funciona só funciona quanto tem uma pasta tipo /ajuda

Vitu disse:

 :-|

po cara ..
o não to conseguindo fazer funcionar.

meu .htaccess ta assim

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?view=$1

e tmb ja dei load no mod_rewrite.so

o que ta faltando?

coloquei o .htaccess no raiz e no teste/

John Marques disse:

recomendo esse tutorial tb muito bom

http://brunotorres.net/urls/comment-page-2#comment-89153

Bruno disse:

Fala cara! estou a um tempo procurando sobre o assunto, achei muitos tutorias os quais me deram uma boa noção! mas ainda não fiquei sem entender qual o papel do RewriteCond e de que outras formas posso utilizar se você tiver domínio sobre o assunto serial legal postar! vlw... fui!

Leonardo Cardoso disse:

Cara, ótimo tutorial!!!
Simples, e direto ao ponto.

Parabéns!

Rafael Gontijo Hamdan disse:

Imagens e arquivos interpretados pelo cliente (client-sided) sumirão caso a URL interpretada pelo php contenha o caractér "/", pois isso fará com que o navegador busque outro endereço (que no caso não existirá).

Uma boa dica para resolver este problema é criar um arquivo de configuração onde vc definirá valores como CONFIG_URL_IMAGES, CONFIG_URL_CSS, entre outros, assim, você incluirá diretamente da webpage "remota" (não há necessidade de fazer isso com includes do PHP, já que são server-sided).

Att,
Rafael H.

Alexandre Broggio disse:

Vlw pelo tuto

Evandro Victor disse:

Ciro,
seu post foi arrasador, agora unica coisa que é necessário contemplar é que se faz necessário habilitar nas configurações do apache a linha "LoadModule rewrite_module modules/mod_rewrite.so"

Albert disse:

Galera, tudo beleza?
Seguinte, estou com um problema que não consigo resolver.

Se alguém souber como fazer isso, por favor, me envia um e-mail me explicando!

Quero que todas as urls:
http://www.meusite.com/?videos=www.videos.com/restante-da-url/
Sejam reescritas para: http://www.meusite.com/videos/restante-da-url/

Conheço algumas coisas de redirecionamento de urls, mas isso não
consigo fazer. Sei que é fácil, mas não tô conseguindo.

E aí, pode me ajudar?

Abraços

Albert
meninoalbert@gmail.com

Schneider disse:

Ótima dica, obrigado!

Leo disse:

Muito bom Ciro,

Mas me tire uma dúvida de leigo no assunto, como faço para as páginas simples como por exempo:

http://www.dominio.com/empresa.php

se transformar em:

http://www.dominio.com/empresa

tem como vc explicar isso amigo?

Tyler Vortex disse:

@Leo, isto resolve?

# aceitando paginas sem extensao
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} (.*)/([^/]+)(\?.*)?$
RewriteCond %1/%2.php -f
RewriteCond %{REQUEST_URI} (.*)/([^/]+)(\?.*)?$
RewriteRule .* %1/%2.php [QSA]

João disse:

Não sei se aqui pode postar dúvida.

É o seguinte, eu uso URL amigáveis da seguinte forma:

RewriteRule ^([a-z,0-9,A-Z,_-]+)\/([a-z,0-9,A-Z,_-]+)$ /forum/viewforum.php?f=$2

Isso é usado em um fórum phpBB3

Ele cria um link, tipo:

http://www.site.com/assunto/1/2

Só que acontece o seguinte: O link é criado sem problema, mas, pelo log de erro do meu cPanel, ele interpreta como se assunto fosse uma pasta, ou seja, um visitante entra em uma página e o servidor achar que esse link é uma pasta, como não encontra a pasta retorna erro. Alguém sabe como resolver?

João disse:

Vlw galera, resolvido em
http://www.codigosnaweb.com/forum/

Leo disse:

Show de bola @Tyler_Vortex , funcionou perfeitamente.

Obrigado

Elton disse:

Fiz meu site e agora vou alterar para url amigaveis, obrigado pela dica!!!

www.adesivarts.com.br

roberto disse:

cara nao entendi nada =//
tem como alguem me ajudar por msn?
to mto perdido nesse assunto de urls amigaveis =/

Gabriel Oliveira disse:

Olá, muito bom mesmo esse modulo do apache, e ta sendo usado cada vez mais.
Eu gostaria da explicação do mod rewrite usado pelo WordPress:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Não entendi as linhas:
RewriteRule ^index\.php$ - [L]
Olá, muito bom mesmo esse modulo do apache, e ta sendo usado cada vez mais.
Eu gostaria da explicação do mod rewrite usado pelo WordPress:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule . /index.php [L]
E gostaria de saber como ele pega o diretorio pelo php, e como interpreta de acordo com a configuração, ex: /%category%/%postname%/ ou /%postname%/
Só gostaria de entender como ele enterpreta isso tudo!
É possivel?  :)

Gabriel Oliveira disse:

Só corrigindo a pergunta de cima que ficou muito doida num sei pq, suahush.

Olá, muito bom mesmo esse modulo do apache, e ta sendo usado cada vez mais.
Eu gostaria da explicação do mod rewrite usado pelo WordPress:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Não entendi as linhas:
RewriteRule ^index\.php$ - [L]
RewriteRule . /index.php [L]

E gostaria de saber como ele pega o diretorio pelo php, e como interpreta de acordo com a configuração, ex: /%category%/%postname%/ ou /%postname%/
Só gostaria de entender como ele enterpreta isso tudo!
É possivel?

Juvenal Lopes disse:

Para nós aqui nada funcionou ???

Kleuton disse:

Prezados, Show a diga!
Porém tenho 2(duas) duvida, e gostaria muito da ajuda de vcs.
1ª -> O fazer, quando o visitante por acaso digita o endereço errado? Vai apresentar erro 404 Página não encontrada, como personalizar ela ??
2ª -> Com o 1º exemplo apresentado acima, de resultados ($url[0], $url[1]... etc). Não deixarei meu site mais vulnerável a invasões?? Pois pensei assim, se um hack enviar um script java exemplo: depois da "/" <script>invadir</script>/ o meu php num vai ler isso ?
Eu não sei formular bem, a segunda pergunta, mais espero q entendam.

Willian Liell disse:

mas esse soh vale para apache?????
e se o o meu servidor nao tiver suporte????

Guilherme Saldanha disse:

O melhor tutorial que vi até agora, simples e eficiente, explicando como tratar de arquivos e pastas.

Lucas Peperaio disse:

Simplesmente o melhor! Parabéns cara

Marcelo Fuchs disse:

Fiz o exemplo acima com os links de exemplo:

http://localhost/teste/index.php?action=classe&method=metodo&var1=valor1&var2=valor2

tentando deixar assim:

http://localhost/teste/index/classe/metodo/var1/valor1/var2/valor2

mas consigo acessar:
http://localhost/teste/
ou
http://localhost/teste/index/

mas nada além disso é passado para a pagina... ou seja... os echo's.. var_dump's não estao funcionando... o que tem de errado???


Ricardo disse:

Ola, eu uso esse script para chamar minhas paginas
[code]
// Inclusao das páginas do site
if (strlen($_GET['p'])>0) {
if (file_exists($_GET['p'].'.php')) {
include($_GET['p'].'.php');
} else {

switch($_GET["p"])
{
default:
include("erro.php");
break;
}

}
} else include("home.php");
[code]
e estou usando o .htaccess
[code]
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(\w+)/?(?:(\d+)/?)? index.php?p=$1&id=$2
[code]

como eu faço para deixa o meu scritp para mim usar esse .htaccess aqui do tutorial?
att,
PauloRicardo
co

Pavanetti disse:

Muito bom esse artigo. Estou iniciando com o htaccess e queria fazer duas regras, mas o resultado de uma colide coma entrada de outra. O que queria fazer para resolver é usar uma lista negada, não de caracteres, mas de strings. Tentei usar um (?! mas não deu. Vi algo que no htaccess dava para usar um ! mas não vi efeito algum. Tem solução.

Gustavo Dutra disse:

Massa, eu tenho um post que falo com mais detalhes a segunda parte do seu post. Falando mais da parte da arquitetura por trás das url's amigáveis. Se quiser conferir, acesse o <a href="http://gustavodutra.com/geek/guia-completo-e-definitivo-de-como-usar-modrewrite">meu post sobre mod_rewrite</a>

Comente:





Comentário enviado!