Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá a todos, vou compartilhar uma solução que julguei ser a melhor forma de trabalhar com URLs amigáveis.
Eu tomei como base um artigo do iMaster escrito pelo Camilo Teixeira de Melo sobre o assunto.
Em resumo, a função do artigo vincula um arquivo a uma URL. Quando chamada, inclui-se o respectivo arquivo.
Exemplificando, vou utilizar o mesmo que tem lá:
http://www.dominio.com/noticias
inclui
http://www.dominio.com/applications/noticias.php
Porém, fazendo alguns testes eu encontrei pontos que poderiam ser melhorados, no sentido de tratar possíveis erros do usuário. Por exemplo, se você adiciona uma barra no final, já não funciona:
http://www.dominio.com/noticias/
Isso eu considero um erro aceitável, isto é, se for considerado um erro. E sendo um pouco mais tolerante, algumas palavras trocadas poderiam ser aceitas. Exemplo:
http://www.dominio.com/noticia
querendo dizer
http://www.dominio.com/noticias
Ou ainda:
http://www.dominio.com/noticias/3
querendo dizer
http://www.dominio.com/noticia/3
Com esse intuito, fiz algumas modificações para que essas situações fossem abrangidas.
:seta: Observação antes de começar:
Seguem os arquivos:
.htaccess
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ main.php
:seta: Sem alterações
config.php
<?php
define('EXTRA_URL', '/site/');
define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST'] . EXTRA_URL);
define('BASE_PATH', $_SERVER['DOCUMENT_ROOT'] . EXTRA_URL);
?>
:seta: Esse arquivo foi criado com as opções básicas da implementação com caminhos absolutos que uso. O EXTRA_URL refere-se às pastas além do domínio, caso a raíz do projeto não seja a raíz do servidor.
urlResponse.php
<?php
require 'config.php';
if(!defined('REQUEST_URI'))
{
$extraUrl = preg_replace('/\/$/', '', EXTRA_URL);
$requestUri = str_replace($extraUrl, '', $_SERVER['REQUEST_URI']);
define('REQUEST_URI', $requestUri);
}
function urlResponse($urlPatterns, $altUrlPatterns) $destiny = '';
foreach($urlPatterns as $pattern => $file)
{
if(preg_match("@^{$pattern}$@", REQUEST_URI, $_GET))
{
$destiny = $file;
break;
}
}
if (!empty($destiny))
{
include BASE_PATH . $destiny;
exit();
}
$redirect = '';
foreach($altUrlPatterns as $pattern => $url)
{
if(preg_match("@^{$pattern}$@", REQUEST_URI, $_GET))
{
$redirect = preg_replace('/^\//', '', $url);
break;
}
}
if (!empty($redirect))
{
$getKeys = array_keys($_GET);
$getKeys = preg_grep('/^[1-9]*$/', $getKeys);
$parameters = '';
if (count($getKeys) > 0)
{
foreach($getKeys as $getKey)
{
$parameters .= '/' . $_GET[$getKey];
}
}
header('Location: ' . BASE_URL . $redirect . $parameters);
exit();
}
include('404.php');
}
?>
:seta: O que mudou?
main.php
<?php
include 'urlResponse.php';
$urlPatterns = array(
'/noticias/?' => 'pages/noticias/index.php',
'/noticia/(?P<idNoticia>\d+)/?' => 'pages/noticias/noticias.php',
'/' => 'pages/index.php'
);
$altUrlPatterns = array(
'/noticia/?' => '/noticias',
'/noticias/(?P<idNoticia>\d+)/?' => '/noticia'
);
urlResponse($urlPatterns, $altUrlPatterns);
?>
:seta: O que mudou?
Pronto! :D
:seta: Concluindo:
http://www.dominio.com/noticias
é acessada por
http://www.dominio.com/noticias
http://www.dominio.com/noticias/
http://www.dominio.com/noticia
http://www.dominio.com/noticia/
E:
http://www.dominio.com/noticia/3
é acessada por
http://www.dominio.com/noticia/3
http://www.dominio.com/noticia/3/
http://www.dominio.com/noticias/3
http://www.dominio.com/noticias/3/
O código pode não ter ficado da melhor maneira, mas eu obtive o que esperava. Espero que possa ser útil de alguma forma. :thumbsup:
Aproveitando o assunto levantado, eu acredito que isso não gere duplicidade, pois eu faço o redirecionamento, ou seja, quando ele acessa:
http://www.dominio.com/noticia/3
http://www.dominio.com/noticia/3/
http://www.dominio.com/noticias/3
http://www.dominio.com/noticias/3/
a URL final é uma só:
http://www.dominio.com/noticia/3
Mesmo assim o Google pode penalizar?
E o motivo eu coloquei no post:
Isso eu considero um erro aceitável, isto é, se for considerado um erro. E sendo um pouco mais tolerante, algumas palavras trocadas poderiam ser aceitas.
É a mesma ideia de comprar domínios com grafias semelhantes para garantir que, caso o usuário digite o domínio principal errado, ele ainda sim acesse o site.
Pessoal,
Sei que esse post é jurássico, mas eu precisava de uma ajudinha de vocês.
Eu configurei esse script em um site, e funcionou td corretamente. Porém, minha pasta /admin/ não funciona nem a pau.
Como faço para criar uma excessão para essas regras?
Tentei editando o arquivo url_response.php e não funcionou.
Tentei tb desabilitar o mod_rewrite na pasta /admin/, o que tb não funcionou.
Alguém aí tem alguma ideia de como eu faço isso?
Obrigado.
Você quer que funcione ou que não funcione?
Imagine o seguinte:
Eu tenho um site, e faço o acesso pelo endereço meudominio.com.br.
Com essa função que você compartilhou com a gente, eu consigo tratar qualquer url no formato /algumacoisa para que a mesma referencie-se a um determinado arquivo.
Só que preciso colocar, por exemplo, um painel administrativo no subdiretorio /admin, e não quero que as páginas contidas nesse subdiretorio sejam tratadas pela mesma função (o que resultaria em um endereço com final /admin/cadastro.php, por exemplo).
Eu tive que fazer algo parecido para utilizar um plugin que passava variáveis via GET, só não tenho o projeto aqui para lembrar em qual arquivo eu fiz o tratamento, mas provavelmente foi no url_response.php, onde você tem a URL acessada.
No meu caso ficou hardcoded a comparação com a URL, pulando a verificação das patterns.
Boa Noite Lucas tudo bem? Primeiramente parabéns pela implementação de melhoria da rotina, muito bom. Uma situação que não consigo entender dentro desta estrutura é: imaginemos o endereço: http://site.com.br/area1/area1a/o-titulo-da-noticia (o título é gerado com uma função usando preg_replace para a hifenização do endereço ok?
O endereço não funciona com a pattern: '/area1/area1a/(?P<titulonoticia>\w+)' mas funciona com '/area1/area1a/(?P<titulonoticia>\S+)'.
Basta incluir um hifen e ela para de funcionar com w+, funcionando apenas com S+, porém gera grandes transtornos. Passando pela validação do url_response e caindo no 404.
Saberia me auxiliar a compreender o por que?
Grato.
bacana @Lucas,
só toma cuidado com isso:
http://www.dominio.com/noticia/3
http://www.dominio.com/noticia/3/
http://www.dominio.com/noticias/3
http://www.dominio.com/noticias/3/
pode você pode gerar uma duplicação de conteúdo pro google, e o teu site ser penalizado.
Se quer ter essa flexibilidade(não sei pq), use alguns canonicals, para não ter problemas de indexamento.