158 votes

Rediriger tout vers index.php en utilisant htaccess

J'écris un simple framework MVC basé sur PHP. Je veux que ce framework puisse être installé dans n'importe quel répertoire.

Mon script PHP saisit l'uri de la requête et la découpe en segments. Il fait du segment 1 le contrôleur et du segment 2 l'action. Tout se passe bien quand je fais ça :

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

Il sera dirigé vers le contrôleur de module et la méthode spécifiques. J'ai maintenant un contrôleur par défaut, le contrôleur home, qui se trouve dans le dossier home.

Maintenant, lorsque j'accède directement à ce dossier http://www.example.com/mvc/home/ Il affichera un 403 forbidden parce que ce dossier existe, mais il doit aussi retourner à http://www.example.com/mvc/index.php

Si j'avais installé le framework dans un autre dossier, disons le dossier framework, il devrait être redirigé vers http://www.example.com/framework/index.php

Je voudrais rediriger chaque dossier et fichier php vers le fichier index.php, en laissant tout le reste tel quel.

Le premier problème que j'ai rencontré est qu'il ne redirige jamais vers le bon dossier, toujours vers le dossier racine du domaine.

C'est ce que j'ai essayé :

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

313voto

CD001 Points 6123

Votre règle de réécriture semble presque correcte.

Assurez-vous d'abord que votre .htaccess se trouve dans votre répertoire de documents (au même endroit que le fichier index.php ) ou cela n'affectera que le sous-dossier dans lequel il se trouve (et tous les sous-dossiers à l'intérieur de celui-ci - de manière récursive).

Ensuite, modifiez légèrement votre règle pour qu'elle ressemble à quelque chose comme ça :

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

Pour l'instant, tu ne fais que correspondre . qui est un d'un caractère quelconque, il faut au moins .* pour correspondre à un nombre quelconque d'occurrences de n'importe quel caractère.

El $_GET['path'] contiendra la fausse structure de répertoire, donc /mvc/module/test par exemple, que vous pouvez ensuite utiliser dans le fichier index.php pour déterminer l'adresse de l'utilisateur. Contrôleur et les actions que vous voulez effectuer.

Si vous voulez que l'ensemble du système soit installé dans un sous-répertoire, tel que /mvc/ o /framework/ La façon la moins compliquée de le faire est de modifier légèrement la règle de réécriture pour en tenir compte.

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

Et assurez-vous que votre index.php se trouve dans ce dossier tandis que le .htaccess se trouve dans la racine du document.

Alternative à $_GET['path'] (mis à jour en février 18 et janvier 19)

Il n'est pas nécessaire (ni même courant aujourd'hui) de définir l'attribut chemin en tant que $_GET variable, de nombreux cadres s'appuient sur $_SERVER['REQUEST_URI'] pour récupérer la même information - normalement pour déterminer quelle Contrôleur à utiliser - mais le principe est exactement le même.

Cela simplifie la RewriteRule légèrement, car vous n'avez pas besoin de créer le fichier chemin (ce qui signifie que le paramètre original de l'OP RewriteRule sera fonctionnent maintenant) :

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

Cependant la règle concernant l'installation dans un sous-répertoire s'applique toujours, par ex.

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

Les drapeaux :

NC = No Case (non sensible à la casse, pas vraiment nécessaire puisqu'il n'y a pas de caractères dans le motif)

L = Last (la réécriture s'arrêtera après cette réécriture, alors assurez-vous que c'est la dernière chose dans votre liste de réécritures).

QSA = Query String Append, juste au cas où vous auriez quelque chose comme ?like=penguins à la fin que vous voulez garder et passer à index.php.

43voto

starkeen Points 29161

Pour rediriger tout ce qui n'existe pas vers index.php vous pouvez également utiliser l'option FallBackResource directive

FallbackResource /index.php

Il fonctionne de la même manière que le ErrorDocument lorsque vous demandez un chemin d'accès ou un fichier inexistant sur le serveur, la directive renvoie silencieusement la demande au serveur. index.php .

Si vous voulez tout rediriger ( including existant files or folders ) à index.php vous pouvez utiliser quelque chose comme ce qui suit :

RewriteEngine on

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

Notez le motif ^((?!index\.php).+)$ correspond à n'importe quel uri sauf index.php nous avons exclu le chemin de destination pour éviter l'erreur de bouclage infini.

22voto

Julio Marchi Points 163

Il existe un "truc" pour cela problème qui s'adapte à tous les scénarios, une solution si évidente que vous devrez l'essayer pour croire qu'elle fonctionne réellement... :)

C'est ici...

<IfModule mod_rewrite.c>

   RewriteEngine On

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

</IfModule>

En gros, vous demandez MOD_REWRITE à transmettre à index.php la demande URI toujours quand un fichier existe ET toujours lorsque le fichier demandé n'existe pas ¡!

En examinant le code source de MOD-REWRITE Pour comprendre comment il fonctionne, j'ai réalisé que toutes ses vérifications ont toujours lieu après la vérification si le fichier référencé existe ou non. Ce n'est qu'ensuite que le RegEx sont traitées. Même si votre URI pointe vers un dossier, Apache appliquera la vérification de la balise fichiers d'index énumérés dans son fichier de configuration.

Sur la base de cette simple découverte, il s'est avéré évident qu'une simple validation de fichier serait suffisante pour tous les appels possibles Dans la mesure où nous effectuons une double vérification de la présence du fichier et acheminons les deux résultats vers le même point final, nous couvrons 100 % des possibilités.

IMPORTANT : Remarquez qu'il n'y a pas de " / " dans index.php . Par défaut, MOD_REWRITE utilisera le dossier qu'il a défini comme "dossier de base" pour la redirection. La beauté de la chose est qu'il ne doit pas nécessairement s'agir du "dossier racine" du site, ce qui permet à cette solution de fonctionner dans les cas suivants localhost/ et/ou tout sous-dossier que vous lui appliquez.

En fin de compte, d'autres solutions que j'ai testées auparavant (celles qui semblaient fonctionner correctement) ne permettaient pas à PHP d'exiger un fichier via son chemin relatif, ce qui est regrettable. Soyez prudent.

Certains diront que c'est une solution peu élégante. C'est peut-être le cas, mais d'après les tests, dans plusieurs scénarios, plusieurs serveurs, plusieurs versions différentes d'Apache, etc., cette solution a fonctionné à 100% dans tous les cas !

18voto

Technoh Points 1009

Vous pouvez utiliser quelque chose comme ça :

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

Cela redirigera toutes les requêtes vers l'index.php du répertoire racine. Notez qu'elle redirigera également les requêtes pour les fichiers existants, tels que les images, les fichiers javascript ou les feuilles de style.

5voto

Antony Points 1408

Réponse idiote mais si vous n'arrivez pas à comprendre pourquoi il ne redirige pas, vérifiez que les éléments suivants sont activés pour le dossier web .

AllowOverride All

Cela vous permettra d'exécuter htaccess qui doit être en cours d'exécution ! (il existe des alternatives mais ne pas les utiliser causera des problèmes). https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X