Estou escrevendo uma estrutura MVC-ish simples baseada em PHP. Eu quero que essa estrutura possa ser instalada em qualquer diretório.
Meu script PHP pega o uri da solicitação e o divide em segmentos. Torna o segmento 1 o controlador e o segmento 2 a ação. Tudo vai bem quando eu faço isso:
http://www.example.com/mvc/module/test/
Irá para o controlador e método específico do módulo. Agora eu tenho um controlador padrão, o controlador doméstico, que está na pasta home.
Agora, quando eu acessar essa pasta diretamente http://www.example.com/mvc/home/ Ele exibirá 403 proibido, porque essa pasta existe, mas também deve voltar para http://www.example.com /mvc/index.php
Se eu tivesse instalado a estrutura em uma pasta diferente, digamos que a estrutura de pastas precise redirecionar para http://www.example.com/framework/index.php
Gostaria de redirecionar todas as pastas e arquivos php de volta para o index.php, deixando todo o resto do jeito que está.
Meu primeiro problema que encontrei foi que ele nunca redireciona para a pasta correta, sempre para a pasta raiz do domínio.
Isto é o que eu tentei:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
index.php
ou redirecionar todas as solicitações feitas para essa pasta específicaindex.php
?Respostas:
Sua regra de reescrita parece quase correta.
Primeiro, verifique se o seu
.htaccess
arquivo está na raiz do documento (no mesmo local queindex.php
) ou afetará apenas a subpasta em que está (e quaisquer subpastas dentro dela - recursivamente).Em seguida, faça uma pequena alteração na sua regra, para que ela se pareça com:
No momento em que você está apenas correspondendo à
.
qual é uma instância de qualquer caractere, você precisa pelo menos.*
corresponder a qualquer número de instâncias de qualquer caractere.A
$_GET['path']
variável conterá a estrutura de diretório falsa, portanto,/mvc/module/test
por exemplo, que você pode usar no index.php para determinar o controlador e as ações que deseja executar.Se você quiser a coisa toda instalado em um sub-diretório, como
/mvc/
ou/framework/
a maneira menos complicada para fazer isso é mudar a regra de reescrita ligeiramente para levar isso em conta.E verifique se você
index.php
está nessa pasta enquanto o.htaccess
arquivo está na raiz do documento.Alternativa para
$_GET['path']
(atualizado em fevereiro de 18 e janeiro de 19)Na verdade, não é necessário (nem mesmo comum agora) definir o caminho como uma
$_GET
variável; muitas estruturas dependerão$_SERVER['REQUEST_URI']
para recuperar as mesmas informações - normalmente para determinar qual Controlador usar - mas o princípio é exatamente o mesmo.Isso simplificar o
RewriteRule
pouco que você não precisa criar o caminho parâmetro (o que significa original do OPRewriteRule
será agora trabalho):No entanto , a regra sobre a instalação em um subdiretório ainda se aplica, por exemplo,
As bandeiras:
NC
= Sem maiúsculas e minúsculas (sem distinção entre maiúsculas e minúsculas, não é realmente necessário, pois não há caracteres no padrão)L
= Último (ele será interrompido após a reescrita, verifique se é a última coisa na sua lista de reescritas)QSA
= String de consulta Anexar, caso você tenha algo parecido?like=penguins
com o final que deseja manter e passar para index.php.fonte
Options +Indexes
e index.php incluído,DirectoryIndex
você pode deixar o index.php completamente e apenas usar/?path=$1
Isso é válido quando reescrever através de .htaccess, em vez de em uma<Directory>
diretiva de tipo httpd-vhosts.conf .$_GET['path']
se adicionarpath=whatever
ao URL.$_GET
isso seria necessário(.*)
... é engraçado, mas o RewriteRule que o OP estava usando há 6 anos não funcionou para eles na época - mas com a arquitetura MVC evoluiu com PHP (como eu coloquei no Atualizado em 18 de fevereiro ) agora ... acho que eles estavam à frente de seu tempo :) Ainda precisa do caminho correto para o/mvc/
diretório, é claro.Para redirecionar tudo o que não existe
index.php
, você também pode usar aFallBackResource
diretivaFunciona da mesma maneira que
ErrorDocument
, quando você solicita um caminho ou arquivo inexistente no servidor, a diretiva define silenciosamente a solicitaçãoindex.php
.Se você deseja redirecionar tudo (
including existant files or folders
) paraindex.php
, pode usar algo como o seguinte:Observe que o padrão
^((?!index\.php).+)$
corresponde a qualquer uri, excetoindex.php
que excluímos o caminho de destino para evitar erros de loop infinito.fonte
DirectoryIndex index.php
*
vez de+
no padrão se desejar redirecionar o próprio caminho raiz também.Você pode usar algo como isto:
Isso redirecionará todas as consultas para o index.php do diretório raiz. Observe que ele também redirecionará as consultas para arquivos existentes, como imagens, arquivos javascript ou folhas de estilo.
fonte
Há um "truque" para esse problema que se adapta a todos os cenários, uma solução tão óbvia que você terá que tentar acreditar que realmente funciona ... :)
Aqui está...
Basicamente, você está pedindo ao MOD_REWRITE para encaminhar para
index.php
a solicitação de URI sempre que um arquivo existe E sempre que o arquivo solicitado não existe !Ao investigar o código-fonte do MOD-REWRITE para entender como ele funciona, percebi que todas as suas verificações sempre acontecem após a verificação, se o arquivo referenciado existe ou não. Somente então os
RegEx
são processados. Mesmo quando o seu URI apontar para uma pasta, o Apache aplicará a verificação dos arquivos de índice listados em seu arquivo de configuração.Com base nessa descoberta simples, tornou-se óbvio que uma validação simples de arquivo seria suficiente para todas as chamadas possíveis , desde que toque duas vezes na verificação de presença de arquivo e roteie os dois resultados para o mesmo ponto final, cobrindo 100% das possibilidades.
IMPORTANTE: Observe que não há " / " em
index.php
. Por padrão, MOD_REWRITE usará a pasta que está definida como "pasta base" para o encaminhamento. A vantagem disso é que ele não precisa necessariamente ser a "pasta raiz" do site, permitindo que esta solução funcione paralocalhost/
e / ou para qualquer subpasta aplicada.Por fim, algumas outras soluções que eu testei antes (aquelas que pareciam estar funcionando bem) quebraram a capacidade do PHP de "exigir" um arquivo por seu caminho relativo, o que é uma chatice. Seja cuidadoso.
Algumas pessoas podem dizer que esta é uma solução deselegante. Pode ser, na verdade, mas quanto aos testes, em vários cenários, vários servidores, várias versões diferentes do Apache, etc., essa solução funcionou 100% em todos os casos!
fonte
FallbackResource index.php
linha funcionava em um Mac (OS X 10.11), mas não no Centos 7.5. No entanto: issoRewriteRule
também reescreve a localização dos arquivos CSS, por exemplo. Como eu precisava redirecionar apenas arquivos PHP, modifiquei a regra paraRewriteRule ^(.*)php$ index.php [L,QSA]
. YMMV.RewriteRule ^(.*)\.php$ index.php [L,NE,QSA]
(que não precisa de condições para funcionar). Hoje em dia, porém, uso uma regra mais barata:,RewriteRule ^.+$ index.php [L,NE,QSA]
que pode ser combinada com as condiçõesRewriteCond %{REQUEST_FILENAME} !-f
eRewriteCond %{REQUEST_FILENAME} !-d
, ou até mesmo,RewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)
para ser verdadeiramente específica.Resposta tola, mas se você não consegue descobrir por que não está redirecionando, verifique se o seguinte está ativado para a pasta da web.
AllowOverride All
Isso permitirá que você execute o htaccess, que deve estar em execução! (existem alternativas, mas não ativadas, causarão problemas https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride )
fonte
Depois de fazer o procedimento, não esqueça de alterar sua âncora, página inicial
Exemplo:
fonte
caso você ainda esteja se perguntando como redirecionar todas as solicitações, caso o diretório exista (para pastas e arquivos principais da estrutura) para o manipulador de índice da estrutura, após algumas tentativas de erro / sucesso, observei que eu só precisava alterar o RewriteCond no .htaccess Arquivo
a condição acima indica "arquivos não encontrados" e "diretórios não encontrados", ok, e se apenas remover a linha "não encontrada" (! -d) e terminar com algo como o abaixo:
Funcionou para mim como um encanto
fonte