Com certeza você que desenvolve sites, blogs, portais ou sistemas voltados para ambiente web alguma vez já trabalhou, já pensou em trabalhar ou pelo menos ouviu falar das famosas URL Amigáveis.
URL amigáveis são na verdade o nome “amigável” que damos ao processo de reescrita(rewrite) de URLs afim de padronizar, organizar, otimizar e tornar mais atraente os links de um site. Além é claro de facilitar aos mecanismos de busca uma boa indexação.
Essa reescrita é a capacidade do servidor de aplicações converter uma URL antes de executá-la. Isso permite a manipulação de barras(/) sem a preocupação de ferir os níveis de diretórios. Por exemplo, imagine o endereço:
www.site.com/index.php?p=noticias&categoria=esportes&id=1055
Confuso né? Difícil de lembrar e “feio” também. Mas usando a reescrita poderíamos tranformar essa URL em algo parecido com:
www.site.com/noticias/esportes/1055
Muito mais elegante, padronizado e fácil de ser encontrada pelo Google, Bing, Yahoo Search e etc.
Bom. Depois de uma breve e informal descrição do que são as URL amigáveis e do que ela pode nos proporcionar, vamos agora ao que realmente interessa. Como configurar, construir e utilizar essas URLs?
Esse é o foco desse post. Só ressaltando que as explicações são voltadas para o servidor apache, pois é gratuito, famoso e mais utilizado no mundo para aplicações php. Em um post futuro falarei sobre o mesmo assunto focando nos servidores IIS.
Então vamos lá.
1º – Como habilitar o módulo de reescrita(mod_rewrite) no Apache?
Se você estiver utilizando uma hospedagem web com apache não se preocupe pois 99% delas já vem com o módulo rewrite habilitado. Se não estiver e você não tiver acesso aos arquivos de configuração(como o httpd.conf) solicite ao seu provedor a habilitação do mesmo. Se estás em um ambiente local, saiba que por padrão no processo de instalação do apache o mod_rewrite vem desabilitado. Para habilitá-lo é só abrir o arquivo de configuração httpd.conf e procurar pelas linhas.
#LoadModule rewrite_module modules/mod_rewrite.so
#AddModule mod_rewrite.c
Se elas estiverem comentadas(com o #), descomente (tirando o #). Deverá ficar assim:
LoadModule rewrite_module modules/mod_rewrite.so
AddModule mod_rewrite.c
Para surtir efeito, salve o arquivo e reinicie o seu servidor apache.
2º – Criando o arquivo .htaccess e definindo as regras de reescrita
O arquivo .htaccess (isso mesmo, arquivo sem nome, só com extensão) é um arquivo de texto para tratar as configurações do apache. Com ele é possível ativar/desativar módulos, restringir acesso a certos arquivos ou pastas, escrever expressões regulares, etc. Ele tem efeito nos arquivos de seu nível de diretório e em todos os sub-diretórios. Logo, o mais interessante é que ele seja criado na raiz do seu projeto.
É dentro do .htaccess que definimos regras de reescritas de URLs. Vamos supor que tenho um pequeno site e que ele possui as páginas Home, Sobre, Noticias e Contato. Vou criar uma regra de reescrita para ele dentro do arquivo .htaccess. Veja:
1 2 3 4 5 | RewriteEngine on RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^([^/]*)$ index.php?pagina=$1 RewriteRule ^([^/]*)/$ index.php?pagina=$1 |
Na linha 1 eu “ligo” a engine (motor) de reescrita. Depois coloco 2 condições para que os diretórios e os arquivos não sejam submetidos à reescrita(Ex: Não queremos que os sub-diretórios imagens ou css seja interpretados como amigáveis quando alguem digitar www.site.com/imagens ou www.site.com/css/estilos.css).
Nas linha 4 e 5 eu defino as regras(rule) de reescrita. Coloquei 2 regras para que uma possível barra no final da URL não cause erros. Assim, tanto www.site.com/sobre e www.site.com/sobre/ irão funcionar.
^(.*)$ index.php?pagina=$1 defini que o que for informado depois da barra será atribuído ao parâmetro “pagina” no arquivo index.php
Assim, as páginas do nosso site ficarão assim:
- www.site.com/home
- www.site.com/sobre
- www.site.com/noticias
- www.site.com/contato
E para facilitar mais ainda, podemos definir dentro de um único arquivo(no caso o index.php) qual página será carregada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php $pagina = $_GET['pagina']; /* Verifica qual é a pagina a ser incluida */ if($pagina == 'home' || !$pagina) include_once('home.php'); else if($pagina == 'sobre') include_once('sobre.php'); else if($pagina == 'noticias') include_once('noticias.php'); else if($pagina == 'contato') include_once('contato.php'); else die('Essa página não existe'); ?> |
Ele pega o parâmetro “pagina” na URL via GET e de acordo com o valor inclui a página correspondente. Se não for uma página válida ele emite um erro (poderia redirecionar para uma página de erro 404).
Agora imaginemos que dentro da parte de notícias agente filtre as mesmas por categorias. Logo precisaremos criar uma nova regra dentro do nosso .htaccess (linhas 6 e 7)
1 2 3 4 5 6 7 | RewriteEngine on RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^([^/]*)$ index.php?pagina=$1 RewriteRule ^([^/]*)/$ index.php?pagina=$1 RewriteRule ^([^/]*)/([^/]*)$ index.php?pagina=$1&categoria=$2 RewriteRule ^([^/]*)/([^/]*)/$ index.php?pagina=$1&categoria=$2 |
Note que o $1 é válido para o 1º parametro informado(vem antes da 1ª barra na URL), o $2 identifica o 2º parâmetro(vem antes da 2ª barra na URL), e assim por diante. Adicionei uma nova regra onde é informado a categoria de noticias via URL no parâmetro “categoria“. Assim, poderemos ter os seguintes links de noticias(dentre outros é claro):
- www.site.com/noticias/esportes
- www.site.com/noticias/politica
- www.site.com/noticias/entrenimento
Com isso, faremos uma modificação no index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php $pagina = $_GET['pagina']; if($pagina == 'home' || !$pagina) include_once('home.php'); else if($pagina == 'sobre') include_once('sobre.php'); else if($pagina == 'noticias'){ $categoria = $_GET['categoria']; /* Verificar qual é a categoria e incluir a pagina correspondente */ if($categoria == 'esportes') include_once('noticias_esportes.php'); else if($categoria == 'politica') include_once('noticias_politica.php'); else if($categoria == 'entretenimento') include_once('noticias_entrenimento.php'); else include_once('noticias.php'); } else if($pagina == 'contato') include_once('contato.php'); else die('Essa página não existe'); ?> |
No exemplo cada categoria inclui uma página distinta, mas como o processo de busca das notícias será feito é você quem define.
E pronto! O post de hoje teve como objetivo auxiliar o processo de configuração do apache para a reescrita e como trabalhar com URL amigáveis. Espero que possa ajudá-los.
Abs.
Siga-me no twitter: @rafaelwendel
muito bom este tutorial, gostei muito mesmo. só acho que tem um erro ali na linha 5 do .htaccess, pelo menos eu mudei aqui e deu certo…
RewriteRule ^([^/]*)$/ index.php?url=$1
a barra esta depois do cifrão, e aqui não estava funcionando quando digitava localhost/urlamigavel/sobre/, então mudei para antes do cifrão e deu certo…
Olá Junior,
Primeiramente obrigado por sua visita aqui no blog.
E realmente eu me atrapalhei com as barras. Elas estavam depois dos cifrões e estava dando erro. Mas já consertei no post e também troquei o parametro url por pagina que também estava errado.
Obrigado pela observação.
Abs
Boa noite Rafael.
Antes de mais nada, parabéns pelo site. Excelentes tutoriais.
Eu sou completamente leigo no contexto de mexer com Apache, faço desenvolvimento estruturado e pra ser mais exato, tenho sistemas já operando dessa forma onde o usuário acessa o caminho absoluto. Não tem segurança alguma, eu sei, mas foi o que deu pra fazer na época e agora é complicado mudar pois o sistema já cresceu absurdamente.
Bem, essa idéia eu gostaria de implementar, porém, gostaria de saber se é possível usar o .htaccess dessa forma:
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]*)$ admin.php?pagina=$1
RewriteRule ^([^/]*)/$ admin.php?pagina=$1
RewriteRule ^([^/]*)/([^/]*)$ admin.php?pagina=$1&categoria=$2
RewriteRule ^([^/]*)/([^/]*)/$ admin.php?pagina=$1&categoria=$2
Ex.:
________________________________
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]*)$ usuario.php?pagina=$1
RewriteRule ^([^/]*)/$ usuario.php?pagina=$1
RewriteRule ^([^/]*)/([^/]*)$ usuario.php?pagina=$1&categoria=$2
RewriteRule ^([^/]*)/([^/]*)/$ usuario.php?pagina=$1&categoria=$2
_____________________________________
Ou seja, colocar dentro do .htaccess uma regra para cada tipo de usuário???
Ex.:
RewriteRule ^([^/]*)$ admin.php?pagina=$1
RewriteRule ^([^/]*)$ usuario.php?pagina=$1
Pois, meu index.php faz a validação do usuário e o direciona para a página inicial correto que busca num diretório todas as páginas que podem ser acessados por aquele usuário em questão
É possível fazer dessa forma???
Obrigado desde já..
Opa…
Ficou meio confuso, mas seria as duas regras juntas:
Ex.:
________________________________
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]*)$ admin.php?pagina=$1
RewriteRule ^([^/]*)/$ admin.php?pagina=$1
RewriteRule ^([^/]*)/([^/]*)$ admin.php?pagina=$1&categoria=$2
RewriteRule ^([^/]*)/([^/]*)/$ admin.php?pagina=$1&categoria=$2
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]*)$ usuario.php?pagina=$1
RewriteRule ^([^/]*)/$ usuario.php?pagina=$1
RewriteRule ^([^/]*)/([^/]*)$ usuario.php?pagina=$1&categoria=$2
RewriteRule ^([^/]*)/([^/]*)/$ usuario.php?pagina=$1&categoria=$2
Agora sim…
Uma outra perguntinha…
Se não for pedir demais, teria como mostrar como fariamos a passagem de parametros usando a URL amigável???
Pergunto isso pois realizo, por exemplo, a alteração de um dado no DB, óbvio, e não sei como passaria os parametros via URL amigável…
Obrigado.
Bom, consegui resolver esse problema Rafael…
Como o seu blog é bastante visto fica a dica pro pessoal…
No caso eu só aumentei a quantidade de parametros…
Desta forma:
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]*)/$ index.php?usuario=$1
RewriteRule ^([^/]*)/([^/]*)/$ index.php?usuario=$1
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ index.php?usuario=$1&pagina=$2&categoria=$3&id=$4
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?usuario=$1&pagina=$2&categoria=$3&id=$4
Dai ficaria da seguinte forma com a url amigável:
admin/usuarios/ver/4
Sendo “admin” o tipo de usuário, “usuarios” diretório que eu estou no momento, “ver” o arquivo php para visualizar um usuário em particular e “4” o ID de um usuário em particular que eu estou vendo…
Obrigado pelo tutorial, ajudou muito!!!
Obrigado pela força Regis. Com certeza o seu código será de grande valia para os outros visitantes.
Abs
Parabéns ia para você compartilhar seu conhecimento. Mais a minha duvida é a seguinte: estou desenvolvendo um site porém tem a seção de noticias.
Utilizo o seguinte parâmetro para exibir a noticia:
http://localhost/cdl/index.php?pg=noticia¬iciaId=9
Qual procedimento para criar a URL AMIGÁVEL?
Olá Caio,
No seu caso, a melhor forma seria:
RewriteRule ^([^/]*)/([^/]*)/$ index.php?pg=$1¬iciaId=$2
Abs!
Galera, meu xampp não está funcionando isso ai corretamente naum, é como se ele abrisse a index.php a partir de uma pasta ai num carrega o meu CSS e as imgs
no meu só funciona corretamente com apenas um paramentro:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]*)$ index.php?p=$1
Olá Fábio,
É porque o navegador entende como sendo um diretório.
O ideal seria você colocar no head do seu html a url base do site ou da pasta onde voce coloca o conteudo publico do site (imagens, scripts, css e etc)
Assim, todos os links do site (inclusive os que importam os css e js) partirão dessa URL como base.
Espero ter ajudado
Abs
outra dica é usar URL absolutas ao invés das relativas
trocar:
href=css/style.css
por:
href=http://seusite.com/css/style.css
Olha, mesmo assim ele num funciona com mais de um parâmetro
estou testando online mesmo..
Agora gostaria de saber como fazer com mais de 3 parametros… pois num funciona nl online.
testei isso
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?pag=$1&categoria=$2&subcat=$3&subsubcat=$4
mais nada funfa.
Olá Fabio,
Que erro está gerando?
Abs!
Amigo como faço na seguinte situação?
Tenho:
http://www.meusite.com.br
http://www.meusite.com.br/
http://www.meusite.com.br/index.php
Quero redirecionar para:
http://www.meusite.com.br/home/
Quero fazer isso no httccess, como faço?
Nao entendi direito o que você quer, mas pode usar o redirecionamento 301
Abs
Obrigado, seu tutorial foi muito útil, parabens
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?usuario=$1&pagina=$2&categoria=$3
As três opções
como eu configuro aqui para poder funcionar as três opções
o caminho “Usuario” seria uma pasta a onde estaria o arquivo “pagina” e categoria seria os arquivos
else if($pagina == ‘noticias’){
$categoria = $_GET[‘categoria’];
/* Verificar qual é a categoria e incluir a pagina correspondente */
if($categoria == ‘esportes’)
include_once(‘noticias_esportes.php’);
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?usuario=$1&pagina=$2&categoria=$3&assunto=$4
As três opções
como eu configuro aqui para poder funcionar as quatro opções
o caminho “Usuario” seria uma pasta a onde estaria o arquivo “pagina”. O arquivo página vão ter três arquivos diferentes. Noticias, informações e computador
e “categoria” seriam três pastas (Noticias, informações e computador)
e “assunto” seriam os arquivos em cada pasta diferente
como ficaria a configuração
else if($pagina == ‘noticias’){
$categoria = $_GET[‘categoria’];
/* Verificar qual é a categoria e incluir a pagina correspondente */
if($categoria == ‘esportes’)
include_once(‘noticias_esportes.php’);
Aguardo contato obrigado 🙂
Gostei muito da explicaçao, funcionou legal, só que eu tive um problema.
quando eu abro “meusite.com/fotos” ele funciona certinho, mas eu criei uma pasta chamada “adm”, que faz a postagem de fotos e videos pro site, ai quando eu tento entrar em “meusite.com/adm” ou “meusite.com/adm/index.php”, ele nao encontra e da erro 404.
procurei bastante no google e nao achei…
o q faço pra corrigir isso?
obrigado
Como faco para criar uma pagina assim http://www.meusite.com/contacto
Diferente do qual voce explicou que ficaria assim:
sem entrar http://www.meusite.com/index?pag=contacto
Gostei, muito bem explicado. GOSTEI
Continue assim compartilhando o seu conhecimento
Abraços
Poxa! Até que enfim encontrei uma explicação clara e objetiva sobre este assunto! Foram 2 meses de muito garimpo! Obrigada por este e pelos tutoriais de CodeIgniter, Rafael! Estão me ajudando bastante, pois quero aprender um Framework e o material sobre outros que encontrei eram muito densos [Zend, Cake etc]. O seu está me ajudando bastante mesmo a entender como funciona e o por quê de algumas sintaxes. Mesmo sendo um post antigo.
Obrigada mesmo!
Olá Priss,
Valeu pela força. Continue visitando o blog.
Abs!
Muito top a matéria …
Parabéns cara, muito valioso este conteúdo.
Porém estou com uma duvida, qual seria a configuração para passar variaves…
ex: /login?usuario=joao&senha=12345
Olá William.
Normal. Só passar as variáveis na URL e recuperar no código como está acostumado a fazer.
Abs!