web-dev-qa-db-fra.com

réécrire l'URL - supprime le dernier / si nécessaire et ajoute .php

J'ai une question simple, mais je n'ai trouvé aucun article qui réponde à ma question. J'ai besoin d'un fichier htaccess qui réécrit les URL afin qu'il supprime la fin / le cas échéant, et ajoute .php quel que soit le dossier dans lequel il se trouve. Essentiellement, voici ce que je veux faire:

http://example.com/login/ -> http://example.com/login.php
http://example.com/login -> http://example.com/login.php
http://example.com/user/test/login/ -> http://example.com/user/test/login.php
http://example.com/user/test/login -> http://example.com/user/test/login.php
http://example.com/$1/$2/$3/$4/ -> http://example.com/$1/$2/$3/$4.php
http://example.com/$1/$2/$3/$4 -> http://example.com/$1/$2/$3/$4.php
http://example.com/$1/$2/$3/ ... /$65/ -> http://example.com/$1/$2/$3/ ... /$65.php

Je veux qu'il réécrive l'URL pour supprimer la barre oblique finale, s'il y en a une, et ajoute .php (mais le faire UNIQUEMENT si le fichier existe). Et il doit prendre en charge le caractère 'générique', ce qui signifie qu'il fonctionne pour tous les fichiers sans avoir à copier le code de chaque fichier. De cette façon, les URL 'semblent propres'.

J'ai trouvé de nombreux articles avec des exemples de fichiers .htaccess similaires à ceux que je souhaite. Mais je n'en ai trouvé aucun sans l'un de ces problèmes:

  1. Il n'utilise pas de réécriture 'générique', je devrais donc copier le code de chaque fichier pour qu'il réécrit l'URL

  2. Il supprime la barre oblique finale, le cas échéant, puis ajoute le nom de fichier à /index.php?file= au lieu de le réécrire dans le fichier.

  3. La réécriture 'générique' ne fonctionne que dans le répertoire racine. Je ne peux pas l'utiliser si les fichiers sont imbriqués comme suit: /$1/$2/$3/$4/.

Est-ce possible? Je n'ai vu personne le faire avant.

Edit: J'attribuerai une prime si quelqu'un arrive avec un fichier .htaccess qui fait tout cela correctement, mais supporte également les paramètres d'URL.

5
Aaron Esau

Je suppose que vous souhaitez supprimer la barre oblique finale (le cas échéant) avec une redirection externe afin de canoniser l'URL, puis d'ajouter le .php extension avec une réécriture interne (c'est-à-dire cachée de l'utilisateur) afin de router correctement l'URL. C'est un processus en deux étapes.

NB: La barre oblique finale doit rester si vous accédez à un répertoire physique.

Utilisation de mod_rewrite dans .htaccess:

RewriteEngine On

# Remove the trailing slash (if any) for non-directories
# This is essentially unconditional in order to canonicalise the URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [R=302,L]

# Append ".php" if that file would exist (internal rewrite / hidden from user)
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]

Changez le R=302 (c'est-à-dire la redirection temporaire) en R=301 pour le rendre permanent. Il est plus facile de tester les 302 car ils ne sont pas mis en cache par le navigateur. (Assurez-vous que le cache du navigateur est vide avant de tester.)

C'est un "wildcard" dans le sens où cela fonctionne pour n'importe quelle profondeur de fichier. .* saisit simplement tout.

Les paramètres d'URL seront ajoutés à la substitution par défaut - rien de spécial à faire à cet égard.


PDATE: Puisque l'URL canonique semblerait être l'URL avec la barre oblique de fin (à laquelle les demandes sont envoyées par POST ) alors ce qui précède devrait être changé comme suit:

RewriteEngine On

# Append .php if that file exists (internal rewrite)
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*?)/?$ $1.php [L]

Cela acceptera les demandes de /path/to/file et de /path/to/file/ et réécrira la demande en interne dans /path/to/file.php. Vous devrez gérer la canonisation de l'URL dans votre script. Si toutes vos URL pointent déjà sur /path/to/file/ (c'est-à-dire avec une barre oblique), vous pouvez modifier la RewriteRule motif et supprimez les deux ? ie. (.*)/$ - cela rend la barre oblique finale obligatoire sur la demande.

3
MrWhite