Apache mod_rewrite
O que você está procurando é o mod_rewrite ,
Descrição: fornece um mecanismo de regravação baseado em regras para regravar URLs solicitados em tempo real.
De um modo geral, mod_rewrite
funciona combinando o documento solicitado com as expressões regulares especificadas e, em seguida, realiza reescritas de URL internamente (dentro do processo apache) ou externamente (no navegador do cliente). Essas reescritas podem ser tão simples quanto traduzir internamente example.com/foo em uma solicitação de example.com/foo/bar.
Os documentos do Apache incluem um mod_rewrite
guia e acho que algumas das coisas que você deseja fazer são abordadas nele. Guia detalhado do mod_rewrite .
Forçar o www
subdomínio
Eu gostaria que fosse forçado "www" antes de cada url, então não é domain.com, mas www.domain.com/page
O guia de reescrita inclui instruções para isso no exemplo de nome de host canônico .
Remova as barras finais (Parte 1)
Eu gostaria de remover todas as barras finais das páginas
Não tenho certeza por que você faria isso, já que o guia de reescrita inclui um exemplo do oposto , ou seja, sempre incluindo uma barra final. Os documentos sugerem que a remoção da barra final tem grande potencial para causar problemas:
Problema de barra final
Descrição:
Todo webmaster pode cantar uma canção sobre o problema da barra final em URLs que fazem referência a diretórios. Se eles estiverem faltando, o servidor descarta um erro, porque se você disser em /~quux/foo
vez de /~quux/foo/
então o servidor procura um arquivo chamado foo. E porque esse arquivo é um diretório, ele reclama. Na verdade, ele tenta se consertar sozinho na maioria dos casos, mas às vezes esse mecanismo precisa ser emulado por você. Por exemplo, depois de fazer muitas reescritas complicadas de URL em scripts CGI, etc.
Talvez você possa explicar por que deseja remover a barra final o tempo todo.
Remover .php
extensão
Eu preciso remover o .php
A coisa mais próxima de fazer isso que posso pensar é reescrever internamente cada documento de solicitação com uma extensão .php, ou seja, example.com/somepage é processado como uma solicitação para example.com/somepage.php. Observe que proceder dessa maneira exigiria que cada alguma página realmente exista como alguma página.php no sistema de arquivos.
Com a combinação certa de expressões regulares, isso deve ser possível até certo ponto. No entanto, posso prever alguns possíveis problemas com as páginas de índice não sendo solicitadas corretamente e não correspondendo aos diretórios corretamente.
Por exemplo, isso irá reescrever corretamente example.com/test como uma solicitação para example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
Mas fará com que example.com não carregue porque não existe example.com/.php
Imagino que, se você remover todas as barras finais, escolher uma solicitação de índice de diretório de uma solicitação de nome de arquivo no diretório pai será quase impossível. Como você determina uma solicitação para o diretório 'foobar':
example.com/foobar
de uma solicitação de um arquivo chamado foobar (que na verdade é foobar.php)
example.com/foobar
Pode ser possível se você usar a RewriteBase
diretiva. Mas se você fizer isso, o problema ficará muito mais complicado, pois você exigirá RewriteCond
diretivas para fazer a verificação no nível do sistema de arquivos se a solicitação mapeia para um diretório ou arquivo.
Dito isso, se você remover o requisito de remover todas as barras finais e, em vez disso, forçar a adição de barras finais, o problema de "nenhuma extensão .php" se torna um pouco mais razoável.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
Isso ainda não é perfeito - toda solicitação de arquivo ainda tem .php anexado à solicitação internamente. Uma solicitação de 'hi.txt' colocará isso em seus registros de erro:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
Mas há outra opção, defina as diretivas DefaultType
e DirectoryIndex
assim:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Atualização de 14/11/2013 - Corrigido o snippet acima para incorporar a observação de Nicorellius
Agora as solicitações para hi.txt (e qualquer outra coisa) são bem-sucedidas, as solicitações para example.com/test retornarão a versão processada de test.php e os arquivos index.php funcionarão novamente.
Devo dar crédito a quem o crédito é devido por esta solução como eu encontrei Michael J. Radwins Blog pesquisando no Google por php no extension apache .
Remova as barras finais
Algumas pesquisas apache remove trailing slashes
me levaram a algumas páginas de otimização de mecanismos de pesquisa. Aparentemente, alguns sistemas de gerenciamento de conteúdo (Drupal, neste caso) disponibilizarão conteúdo com e sem uma barra final em URls, o que, no mundo do SEO, fará com que seu site incorra em uma penalidade de conteúdo duplicado. Fonte
A solução parece bastante trivial, usando mod_rewrite
we reescrever na condição de que o recurso solicitado termina em a /
e reescrever a URL enviando de volta o 301 Permanent Redirect
cabeçalho HTTP.
Aqui está seu exemplo, que assume que seu domínio é blamcast.net e permite que a solicitação seja opcionalmente prefixada com www.
.
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Agora estamos chegando a algum lugar. Vamos juntar tudo e ver como fica.
Obrigatório www.
, não .php
e sem barras finais
Isso pressupõe que o domínio é foobar.com e está sendo executado na porta 80 padrão.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.com/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
O sinalizador 'R' é descrito na RewriteRule
seção de diretiva. Snippet:
redirect|R [=code]
(forçar redirecionamento) Substituição de prefixo com
http://thishost[:thisport]/
(o que torna a nova URL um URI) para forçar um redirecionamento externo. Se nenhum código for fornecido, uma resposta HTTP de 302 ( MOVED TEMPORARIAMENTE ) será retornada.
Nota Final
Não consegui fazer a remoção da barra funcionar com sucesso. O redirecionamento acabou me dando loops de redirecionamento infinitos. Depois de ler a solução original mais de perto, tenho a impressão de que o exemplo acima funciona para eles por causa de como a instalação do Drupal está configurada. Ele menciona especificamente:
Em um site Drupal normal, com URLs limpos habilitados, esses dois endereços são basicamente intercambiáveis
Em referência a URLs que terminam com e sem barra. Além disso,
Drupal usa um arquivo chamado .htaccess
para dizer ao seu servidor web como lidar com URLs. Este é o mesmo arquivo que ativa a mágica de URL limpa do Drupal. Ao adicionar um comando de redirecionamento simples ao início do
.htaccess
arquivo, você pode forçar o servidor a remover automaticamente quaisquer barras finais.