Reindirizza tutto a index.php usando htaccess


131

Sto scrivendo un semplice framework MVC basato su PHP. Voglio che questo framework possa essere installato in qualsiasi directory.

Il mio script PHP acquisisce l'uri della richiesta e lo suddivide in segmenti. Rende il segmento 1 il controller e il segmento 2 l'azione. Va tutto bene quando lo faccio:

http://www.example.com/mvc/module/test/

Andrà al controller e al metodo del modulo specifico. Ora ho un controller predefinito, il controller home, che si trova nella cartella home.

Ora quando accedo direttamente a questa cartella http://www.example.com/mvc/home/ Mostrerà un 403 proibito, perché questa cartella esiste, invece dovrebbe anche tornare a http://www.example.com /mvc/index.php

Se avessi installato il framework in una cartella diversa, diciamo che il framework della cartella deve essere reindirizzato a http://www.example.com/framework/index.php

Vorrei reindirizzare ogni cartella e file php su index.php, lasciando tutto il resto com'è.

Il mio primo problema che ho riscontrato è stato che non reindirizza mai alla cartella giusta, sempre alla cartella principale del dominio.

Questo è quello che ho provato:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

Solo per assicurarmi di aver capito correttamente la tua domanda: vuoi reindirizzare ogni richiesta alla radice index.php o vuoi reindirizzare ogni richiesta fatta a quella specifica cartella index.php ?
Technoh

Nella cartella in cui si trova il file htaccess, la directory principale del framework. Nel mio esempio torna alla directory mvc
David Ericsson

Risposte:


259

La tua regola di riscrittura sembra quasi a posto.

Per prima cosa assicurati che il tuo .htaccessfile sia nella root del documento (nello stesso posto in cui si trova index.php) o influenzerà solo la sottocartella in cui si trova (e tutte le sottocartelle al suo interno - in modo ricorsivo).

Quindi apporta una leggera modifica alla regola in modo che assomigli a:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

Al momento si sta solo corrispondente su .che è un esempio di carattere, è necessario almeno .*per adattarsi a qualsiasi numero di istanze di qualsiasi carattere.

La $_GET['path']variabile conterrà la falsa struttura della directory, quindi, /mvc/module/testad esempio, che puoi utilizzare in index.php per determinare il controller e le azioni che desideri eseguire.


Se vuoi che l'intero shebang sia installato in una sottodirectory, come /mvc/o /framework/il modo meno complicato per farlo è cambiare leggermente la regola di riscrittura per tenerne conto.

RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]

E assicurati di index.phpessere in quella cartella mentre il .htaccessfile è nella root del documento.


Alternativa a$_GET['path'] (aggiornato febbraio '18 e gennaio '19)

Non è effettivamente necessario (e nemmeno comune ora) impostare il percorso come $_GETvariabile, molti framework si baseranno su $_SERVER['REQUEST_URI']per recuperare le stesse informazioni - normalmente per determinare quale Controller usare - ma il principio è esattamente lo stesso.

Ciò semplifica l' RewriteRuleleggermente mentre non è necessario per creare il percorso del parametro (che significa originale del PO RewriteRule sarà ora di lavoro):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

Tuttavia , la regola sull'installazione in una sottodirectory si applica ancora, ad es

RewriteRule ^.*$ /mvc/index.php [L,QSA]



Le bandiere:

NC = Nessuna distinzione tra maiuscole e minuscole (non fa distinzione tra maiuscole e minuscole, non realmente necessaria poiché non ci sono caratteri nel modello)

L = Last (smetterà di riscrivere dopo questa riscrittura quindi assicurati che sia l'ultima cosa nella tua lista di riscritture)

QSA= Stringa di query Aggiungi, nel caso avessi qualcosa di simile ?like=penguinsalla fine che vuoi mantenere e passare a index.php.


1
dovrebbe essere index.php? path = $ 1
Jacek Pietal

1
@Prozi se non siete in una sotto-directory e index.php è nel docroot, allora è necessario il leader / - con Options +Indexese index.php inclusi in DirectoryIndexsi poteva lasciare fuori index.php del tutto e basta usare /?path=$1Questo vale quando riscrive tramite .htaccess piuttosto che in una <Directory>direttiva di tipo httpd-vhosts.conf .
CD001

Se lo usi e ti affidi a $ _GET ['path'] sarai nei guai in caso di passaggio al server nginx ...
barell

3
Bel post! Vale la pena notare che l'utente può sovrascrivere $_GET['path']se aggiunge path=whateverall'URL.
rybo111

1
@Liviuge - vero, ma inizialmente stavo passando l'intero percorso fino a $_GETquindi avrebbe richiesto (.*)... è divertente ma la RewriteRule che l'OP stava usando 6 anni fa non funzionava per loro allora - ma con il modo in cui l'architettura MVC ha evoluto con PHP (come ho inserito nel bit aggiornato del 18 febbraio ) ora sarebbe ... immagino che fossero in anticipo sui tempi :) /mvc/Ovviamente ha ancora bisogno del percorso corretto per la directory.
CD001

28

Per reindirizzare tutto ciò che non esiste index.php, puoi anche utilizzare la FallBackResourcedirettiva

FallbackResource /index.php

Funziona come ErrorDocument, quando richiedi un percorso o un file inesistente sul server, la direttiva formula silenziosamente la richiesta a index.php.

Se vuoi reindirizzare tutto ( including existant files or folders) a index.php, puoi usare qualcosa come il seguente:

RewriteEngine on

RewriteRule ^((?!index\.php).+)$ /index.php [L]

Nota che il modello ^((?!index\.php).+)$ corrisponde a qualsiasi uri tranne per il fatto index.phpche abbiamo escluso il percorso di destinazione per evitare errori di loop infiniti.


Ma potresti anche voler usare:DirectoryIndex index.php
Shao

1
Usa *invece che +nel pattern se vuoi reindirizzare anche il percorso di root stesso.
Mir-Ismaili

15

Puoi usare qualcosa del genere:

RewriteEngine on
RewriteRule ^.+$ /index.php [L]

Questo reindirizzerà ogni query al index.php della directory principale. Nota che reindirizzerà anche le query per i file esistenti, come immagini, file javascript o fogli di stile.


1
Questa soluzione ha quasi funzionato per me. Continuavo a ricevere "AH00124: la richiesta ha superato il limite di 10 reindirizzamenti interni". Ho aggiunto "RewriteRule ^ index \ .php - [L]" prima e funziona perfettamente!
Fredster

11

C'è un "trucco" per questo problema che si adatta a tutti gli scenari, una soluzione così ovvia che dovrai provarla per credere che funzioni davvero ... :)

Ecco qui...

<IfModule mod_rewrite.c>

   RewriteEngine On

   RewriteCond %{REQUEST_FILENAME}  -f [OR]
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php [L,QSA]

</IfModule>

Fondamentalmente, stai chiedendo a MOD_REWRITE di inoltrare index.phpla richiesta URI sempre quando esiste un file E sempre quando il file richiesto non esiste !

Nell'indagare il codice sorgente di MOD-REWRITE per capire come funziona mi sono reso conto che tutti i suoi controlli avvengono sempre dopo la verifica se il file di riferimento esiste o meno. Solo allora RegExvengono elaborati. Anche quando il tuo URI punta a una cartella, Apache imporrà il controllo dei file di indice elencati nel suo file di configurazione.

Sulla base di questa semplice scoperta, è diventato ovvio che una semplice convalida del file sarebbe sufficiente per tutte le chiamate possibili , purché tocchi due volte il controllo della presenza del file e instradiamo entrambi i risultati allo stesso punto finale, coprendo il 100% delle possibilità.

IMPORTANTE: nota che non c'è " / " in index.php. Per impostazione predefinita, MOD_REWRITE utilizzerà la cartella impostata come "cartella di base" per l'inoltro. Il bello è che non deve necessariamente essere la "cartella principale" del sito, consentendo a questa soluzione di funzionare per localhost/e / o qualsiasi sottocartella in cui viene applicata.

Alla fine, alcune altre soluzioni che ho testato prima (quelle che sembravano funzionare bene) hanno rotto la capacità di PHP di "richiedere" un file tramite il suo percorso relativo, il che è un peccato. Stai attento.

Alcune persone potrebbero dire che questa è una soluzione poco elegante. Può essere, in realtà, ma per quanto riguarda i test, in diversi scenari, diversi server, diverse versioni di Apache, ecc., Questa soluzione ha funzionato al 100% in tutti i casi!


Grazie, questo ha risolto il mio problema per cui una FallbackResource index.phplinea funzionava su un Mac (OS X 10.11) ma non sotto Centos 7.5. Tuttavia: questo RewriteRuleriscrive anche la posizione dei file CSS, ad esempio. Poiché avevo bisogno di reindirizzare solo i file PHP, ho modificato la regola in RewriteRule ^(.*)php$ index.php [L,QSA]. YMMV.
Laryx Decidua

1
Sono felice che abbia aiutato. Hai ragione, prende di mira TUTTI i file perché la domanda era: " Reindirizza tutto a index.php usando htaccess ". Esistono altri modi più eleganti per reindirizzare solo i file PHP, come RewriteRule ^(.*)\.php$ index.php [L,NE,QSA](che non ha bisogno di condizioni per funzionare). Al giorno d'oggi, tuttavia, utilizzo una regola più economica:, RewriteRule ^.+$ index.php [L,NE,QSA]che può essere combinata con le condizioni RewriteCond %{REQUEST_FILENAME} !-fe RewriteCond %{REQUEST_FILENAME} !-d, o anche, RewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)essere veramente specifica.
Julio Marchi

5

Risposta sciocca ma se non riesci a capire perché non viene reindirizzato, controlla che quanto segue sia abilitato per la cartella web ..

AllowOverride All

Questo ti permetterà di eseguire htaccess che deve essere in esecuzione! (ci sono alternative ma non attive causeranno problemi https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride )


0

Dopo aver fatto il non dimenticare di cambiare il tuo anchor tag, home

Esempio:

.htacces file
RewriteEngine On

RewriteRule ^about/$ /about.php

PHP file:
<a href="about/"> about</a>

Ricorda sempre di cambiare il tag <a>.
Collins Benson

2
Cosa significa dopo aver fatto il non modificare il tag, significa casa ?
Enrico Maria De Angelis

0

nel caso in cui ti stessi ancora chiedendo come reindirizzare tutte le richieste se la directory esiste (per cartelle e file del framework principale) al gestore dell'indice del framework, dopo alcuni tentativi di errore / successo appena notato che avevo solo bisogno di cambiare il RewriteCond nel .htaccess file

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

la condizione precedente indica "file non trovati" e "directory non trovate", ok, e se rimuovesse semplicemente la riga "non trovato" (! -d) e terminasse con qualcosa di simile al seguente:

RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]

Ha funzionato per me come un fascino

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.