152 votes

Référence: mod_rewrite, réécriture d'URL et "jolis liens" expliqués

"Assez de liens" est souvent un thème demandé, mais il est rarement pleinement expliqué. le mod_rewrite est une façon de faire "à peu des liens", mais c'est complexe et que sa syntaxe est très laconique, difficile à analyser et de la documentation suppose un certain niveau de compétence dans HTTP. Quelqu'un peut m'expliquer en termes simples comment "liens jolie" travail et comment mod_rewrite peut être utilisé pour les créer?

Autres noms communs, des noms d'emprunt, les conditions pour l'assainissement de l'url: Reposant Url, User-friendly URLs, SEO-friendly URLs, les Coups de liquide, MVC url (sans doute un abus de langage)

120voto

deceze Points 200115

Pour comprendre ce que mod_rewrite ne vous devez d'abord comprendre comment un serveur web fonctionne. Un serveur web répond à des requêtes HTTP. Une requête HTTP à son niveau de base ressemble à ceci:

GET /foo/bar.html HTTP/1.1

C'est la simple demande d'un navigateur à un serveur web demandant l' URL /foo/bar.html . Il est important de souligner qu'il ne demande pas un fichier, il demande juste quelques URL arbitraire. La demande peut également ressembler à ceci:

GET /foo/bar?baz=42 HTTP/1.1

C'est une demande pour une URL, et il a évidemment plus rien à faire avec les fichiers.

Le serveur web est une application qui écoute sur un port, d'accepter les requêtes HTTP provenant de ce port et de renvoyer une réponse. Un serveur web est entièrement libre de répondre à toute demande en aucune façon qu'il lui fit et de la manière que vous l'avez configuré pour répondre. Cette réponse n'est pas un fichier, il est une réponse HTTP qui peut ou peut ne pas avoir quelque chose à voir avec la physique des fichiers sur un disque. Un serveur web n'a pas à être d'Apache, il existe de nombreux autres serveurs web qui sont tout simplement les programmes qui s'exécutent de façon persistante et sont attachés à un port de répondre à des requêtes HTTP. Vous pouvez écrire vous-même. Ce paragraphe a pour objet de divorce vous de la notion que les URLs directement l'égalité des fichiers, ce qui est vraiment important de le comprendre. :)

La configuration par défaut de la plupart des serveurs web est de chercher un fichier qui correspond à l'URL sur le disque dur. Si le document root du serveur est configuré pour, disons, /var/www, il peut regarder si le fichier /var/www/foo/bar.html existe et servir de ce si. Si le fichier se termine par ".php" qu'il invoquera le PHP et ensuite retourner le résultat. Tous les cette association est totalement paramétrable; un fichier n'a pas de fin ".php pour le serveur web à exécuter par le biais de l'interprète PHP, et l'URL ne doit pas correspondre à un fichier particulier sur le disque pour que quelque chose arrive.

mod_rewrite est une façon de réécrire l'interne de traitement de la demande. Lorsque le serveur web reçoit une requête de l'URL /foo/bar, vous pouvez réécrire cette URL dans quelque chose d'autre avant que le serveur web va chercher un fichier sur le disque pour le match. Exemple Simple:

RewriteEngine On
RewriteRule   /foo/bar /foo/baz

Cette règle dit que chaque fois qu'une requête correspond à "/foo/bar", de le réécrire "/foo/baz". La demande sera ensuite traitée comme si /foo/baz avait été demandé. Ceci peut être utilisé pour des effets différents, par exemple:

RewriteRule (.*) $1.html

Cette règle correspond à rien (.*) et la capture ((..)), puis réécrit à ajouter ".code html". En d'autres termes, si /foo/bar a été l'URL demandée, elle sera traitée comme si /foo/bar.html a été demandé. Voir http://regular-expressions.info pour plus d'informations sur la correspondance d'expressions régulières, de la capture et de remplacement.

Une autre rencontre souvent la règle est ceci:

RewriteRule (.*) index.php?url=$1

Encore une fois, cela correspond à rien et réécrit le fichier index.php à l'origine de la requête URL ajoutés dans l' url paramètre de requête. I. e., pour toute demande de venir dans, le fichier index.php est exécutée et que ce fichier va avoir accès à l'original de la demande en $_GET['url'], donc il peut faire ce qu'il veut avec elle.

Ce mod_rewrite ne pas faire

mod_rewrite n'est pas la baguette magique pour faire de votre Url "joli". C'est une erreur courante. Si vous avez ce lien dans votre site web:

<a href="http://stackoverflow.com/my/ugly/link.php?is=not&amp;very=pretty">

il n'y a rien mod_rewrite peut faire pour que jolie. Afin de rendre cette un joli lien, vous devez:

  1. Modifier le lien à un joli lien:

    <a href="http://stackoverflow.com/my/pretty/link">
    
  2. Utiliser mod_rewrite sur le serveur pour traiter la requête à l'URL /my/pretty/link l'aide de l'une des méthodes décrites ci-dessus.

  3. On pourrait utiliser mod_substitute dans le cadre de transformer sortant HTML des pages et leurs contenus des liens. Si c'est usally plus d'efforts que juste la mise à jour de vos ressources HTML.

Il y a beaucoup mod_rewrite peut faire et très complexe de règles de correspondance, vous pouvez créer, y compris le chaînage de plusieurs réécritures, l'utilisation de proxy demandes à un tout autre service ou à la machine à, de retour spécifique des codes d'état HTTP réponses, en redirigeant les requêtes etc. Il est très puissant et peut être utilisé pour beaucoup de bien si vous comprenez les fondamentaux de la requête HTTP-mécanisme de réaction. Il n'est pas automatiquement vos liens assez.

Voir la documentation officielle pour tous les indicateurs possibles et les options.

87voto

Nick Points 4016

Pour développer sur deceze de réponse, je voulais vous donner quelques exemples et explication de certains autres mod_rewrite fonctionnalité.

Tous les exemples ci-dessous supposent que vous avez déjà incluses RewriteEngine On votre .htaccess le fichier.

Exemple De Réécriture

Prenons cet exemple:

RewriteRule ^/blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=$1&title=$2 [NC,L,QSA]

La règle est divisé en 4 sections:

  1. RewriteRule - démarre la règle de réécriture
  2. ^/blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ - Ce qui est appelé le modèle, mais je vais juste faire référence à elle comme à la gauche de la règle - ce que vous voulez de réécriture à partir de
  3. /blog/index.php?id=$1&title=$2 - disant la substitution, ou à la droite d'une règle de réécriture - ce que vous voulez de réécrire
  4. [NC,L,QSA] sont des indicateurs de la règle de réécriture, séparés par une virgule, comme je l'expliquerai plus tard

La réécriture ci-dessus permettrait de vous relier à quelque chose comme /blog/1/foo/ et il serait en fait la charge /blog/index.php?id=1&title=foo.

Côté gauche de la règle

  • ^ indique le début du nom de la page - il réécrire l' example.com/blog/... mais pas example.com/foo/blog/...
  • Chaque jeu de crochets représente une expression régulière que nous pouvons saisir en tant que variable dans le côté droit de la règle. Dans cet exemple:
    • la première série de crochets - ([0-9]+) - correspond à une chaîne de longueur non spécifiée avec uniquement des valeurs numériques (c'est à dire de 0 à 9), et se rapporte à l' $1 dans le côté droit de la règle
    • la deuxième série de crochets correspond à une chaîne de longueur non spécifiée contenant des caractères alphanumériques (A-Z, a-z ou 0-9) et permet de caractères - ou + (note + est échappé avec une barre oblique inverse comme, sans s'y soustraire execute comme un regex répétition de caractères), et se rapporte à l' $2 dans la partie droite de la règle
  • ? signifie que le caractère précédent est facultatif, donc dans ce cas, les deux /blog/1/foo/ et /blog/1/foo de la réécrire à la même place
  • $ indique que c'est la fin de la chaîne, nous voulons match

Drapeaux

Ce sont des options qui sont ajoutés entre crochets à la fin de vos règles de réécriture pour spécifier certaines conditions. Encore une fois, il ya beaucoup de différentes options qui vous pouvez lire dans la documentation, mais je vais passer par certaines des plus commune des drapeaux:

NC

Le no cas indicateur signifie que la règle de réécriture est insensible à la casse, donc pour l'exemple de la règle ci-dessus, cela signifierait que les deux /blog/1/foo/ et /BLOG/1/foo/ (ou toute variation de ce) sera associé.

L

Le dernier indicateur indique que c'est la dernière règle qui doit être traitée. Cela signifie que si et seulement si cette règle s'applique, pas d'autres règles seront évalués en fonction de la demande actuelle. Si la règle ne correspond pas, toutes les autres règles s'être essayé dans l'ordre, comme d'habitude. Si vous ne définissez pas l' L drapeau, toutes les règles suivantes seront appliquées à l' réécrit l'URL par la suite.

QSA

La chaîne de requête ajout indicateur nous permet de passer en variables supplémentaires à l'URL spécifiée qui sera ajouté à l'original des paramètres get. Pour notre exemple, cela signifie que quelque chose comme /blog/1/foo/?comments=15 charge /blog/index.php?id=1&title=foo&comments=15

R

Ce drapeau n'est pas celui que j'ai utilisé dans l'exemple ci-dessus, mais je pensais que vaut la peine de mentionner. Cela vous permet de spécifier une redirection http, avec la possibilité d'inclure un code de statut (par exemple, R=301). Par exemple, si vous vouliez faire une redirection 301 sur /myblog/ de /blog/ vous pouvez tout simplement écrire une règle quelque chose comme ceci:

RewriteRule ^/myblog/(*.)$ /blog/$1 [R=301,QSA,L]

Réécrire Les Conditions

Réécrire les conditions de faire réécrit encore plus puissant, vous permettant de spécifier réécrit pour des situations particulières. Il y a un grand nombre de conditions dont vous pouvez lire dans la documentation, mais je reviendrai sur quelques exemples communs et de les expliquer:

# if the host doesn't start with www. then add it and redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

C'est une pratique très courante, qui ajoute votre nom de domaine avec www. (si elle n'y est pas déjà) et d'exécuter une redirection 301. Par exemple, le chargement jusqu' http://example.com/blog/ il vous redirigent vers des http://www.example.com/blog/

# if it cant find the image, try find the image on another domain
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)$ http://www.example.com/$1 [L]

C'est un peu moins commun, mais c'est un bon exemple d'une règle qui ne s'est pas exécuté si le nom de fichier est un répertoire ou un fichier existant sur le serveur.

  • %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC] n'exécutera la réécriture des fichiers avec une extension de fichier de format jpg, jpeg, gif ou png (insensible à la casse).
  • %{REQUEST_FILENAME} !-f va vérifier pour voir si le fichier existe sur le serveur actuel, et exécuter uniquement les réécrire si ce n'est pas
  • %{REQUEST_FILENAME} !-d va vérifier pour voir si le fichier existe sur le serveur actuel, et exécuter uniquement les réécrire si ce n'est pas
  • La réécriture va tenter de charger le même fichier sur un autre domaine

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