wiki.phpfreakz.nl
Aanmelden Artikel Overleg Bewerk Geschiedenis Go to the site toolbox

Mod rewrite

mod_rewrite is een module binnen Apache waarmee opgevraagde URL's door Apache zelf kunnen worden herschreven volgens een aantal instelbare regels.

Dit wordt veel gebruikt om de zogenaamde 'gebruiksvriendelijke' URL's te gebruiken bij PHP scripts. Een URL als /agenda/evenementen/2007/06 wordt dan bijvoorbeeld herschreven naar agenda.php?type=evenementen&jaar=2007&maand=06

Inhoud

Waarschuwing vooraf

Rewrite rules staan in de webmaster wereld bekend onder de uitdrukking 'Voodoo. Damn cool voodoo, but still Voodoo' Met rewrite rules kun je de diepere magie van Apache oproepen en dat kan spectaculaire resultaten opleveren. Een van die resultaten is de bekende oneindige lus, waarbij regel X iets herschrijft wat door regel Y weer wordt herschreven waardoor het door regel X weer wordt herschreven waardoor regel Y... nouja, een heel erg drukke webserver waar niemand meer tussen komt tot Apache er tabak van heeft.

De vuistregel met rewrite rules is: Ga nooit een rewrite rule ontwikkelen op een productieserver, test het altijd uit op een testmachine en als hij daar werkt mag het naar productie.

Installatie

mod_rewrite wordt tegenwoordig vrijwel als standaard aangezet in Apache installaties. Om te controleren of de module in jouw installatie ook beschikbaar is, kan je in een phpinfo(); output kijken bij de geladen modules van Apache. Als daar 'mod_rewrite' tussen staat kan je rechtstreeks gebruik maken van de module.

Als de module nog niet beschikbaar is dan zul je het moeten activeren en hoe dat gaat hangt af van welke installatie je hebt.

Als je niet zelf host dan is het een kwestie van contact opnemen met je host. Als je zelf een Windows host hebt dan kun je meestal in httpd.conf de juiste LoadModule regel aanzetten (of toevoegen): LoadModule rewrite_module modules/mod_rewrite.so Als je op linux Apache met loadable modules hebt geinstalleerd kun je hetzelfde doen als voor Windows. Als je op linus Apache zonder loadable moduiles support hebt dan zul je Apache moeten hercompileren met rewrite support. Neem daarvoor bij het uitvoeren van het configure commando de optie '--enable-rewrite' op. Meer informatie hierover is te vinden op de installatie pagina van Apache.

Rules definiëren

Je maakt gebruik van mod_write door regels op te nemen die Apache vertellen hoe je de URL wilt omschrijven. Zo'n regel kan bijvoorbeeld zijn:

Als de URL begint met 'archief/' en gevolgd wordt door 4 getallen, roep dan 'archief.php' aan met het jaartal dat meegegeven is.

In dit voorbeeld zouden dus de volgende vertalingen gemaakt worden:

Zoals je ziet is de originele URL veel gebruiksvriendelijker dan de archief.php variant. De PHP variant zal je echter altijd gebruiken als je PHP scripts schrijft. mod_rewrite vormt de brug tussen beide varianten.

.htaccess of httpd.conf

Rewrite rules van mod_rewrite kunnen in httpd.conf staan, maar omdat je daarvoor systeembeheerder moet zijn zet je ze meestal in .htaccess bestanden die gewoon in je documentroot kunnen staan. De regels in een htaccess bestand gelden voor alle bestanden die staan in de directory waar het htaccess bestand in staat, plus alle bestanden in alle subdirs van dir directory. Let dus goed op waar je het bestand neerzet, meestal wil je de hele site ermee bedienen en dan zet je het in de documentroot zelf, maar als je uitzonderingen wilt maken dan kun je b.v. een tweede bestand in een subdir zetten.


In het .htaccess bestand neem je een aantal regels op waarmee je de werking van mod_rewrite bepaalt. Uitgebreide informatie over al deze zogenaamde 'directives' is ook te vinden op de mod_rewrite handleiding van Apache

RewriteEngine

Het eerste wat je sowieso nodig hebt in het htaccess bestand is het commando om de rewrite rules aan te zetten: RewriteEngine

RewriteEngine On

RewriteRule

Een rewrite rule is het hart van de omschrijving. Via een reguliere expressie geef je aan op welke URL de regel van toepassing moet zijn en waar deze eventueel naar omgeschreven dient te worden. Een voorbeeld van het eerder genoemde archief voorbeeld zou er als volgt uit zien:

RewriteEngine On
 
RewriteRule ^archief/([0-9]{4})$  archief.php?year=$1

Het eerste argument van de directive is de URL die je wilt herschrijven. Dit kan gewoon een string zijn met een volledige URL, maar ook een reguliere expressie. In het bovenstaande voorbeeld zeg je het volgende:

  • ^: Het begin van de URL
  • archief/: verwacht eerst de string 'archief/'
  • ([0-9]{4}): verwacht 4 keer een karakter dat in het bereik 0-9 zit
  • $: het einde van de URL

Deze reguliere expressie omvat dus alle URL's met een 4 cijferig jaartal. Vervolgens stuur je deze aanvraag door naar de nieuwe URL die je als tweede argument meegeeft. In dit geval is dat een PHP bestand met een get variabele 'year'.

$1 staat voor het eerste gedeelte waar haakjes omheen staan in de reguliere expressie. In dit geval bevat dat dus altijd de vier cijfers van het jaartal. Als er nog een stuk van de expressie tussen haken zou staan dan zou je dat op kunnen roepen met $2, etc. $0 bevat de volledige URL waar je mee begon.

Voorbeeld met 2 argumenten:

RewriteEngine On
 
RewriteRule ^archief/([0-9]{4})$  archief.php?year=$1
RewriteRule ^archief/([0-9]{4})/([0-9]{1,2})$  archief.php?year=$1&month=$2

de url /archief/2007/07 wordt nu omgezet naar /archief.php?year=2007&month=07 dit geldt ook voor /archief/2007/7, omdat 1 óf 2 cijfers verwacht worden.

De eerste rewrite rule is niet van toepassing, omdat de $ afdwong dat na de 4 cijfers van het jaartal geen tekens meer volgden.


Door de reguliere expressies zijn in principe oneindig veel omschrijvingen mogelijk. Reguliere expressies zijn te complex om in dit artikel te behandelen.

RewriteCond

In veel gevallen zal je de rewrite rule alleen willen toepassen onder bepaalde voorwaarden. Via de RewriteCond directive kan je een voorwaarde geven aan een regel. Dit is veel gebruikt om bijvoorbeeld te bepalen of een bepaald bestand op het bestandsysteem wel of niet bestaat.

Indien je alle URL's die je ontvangt wilt doorsturen naar je PHP script, dan je daarvoor een RewriteRule schrijven. Dit zorgt er alleen voor dat ook aanvragen van afbeeldingen en stylesheets bij je PHP script terecht komen. Vaak wil je dit niet, dus zou je willen dat mod_rewrite voor jouw kijkt of het bestand dat men probeert op te vragen toevallig echt bestaat. Deze controle is via een RewriteCond toe te voegen:

RewriteEngine On
 
# Controleer of het geen bestaande directory is
RewriteCond %{REQUEST_FILENAME} !-d
# Controleer of het geen bestaand bestand is
RewriteCond %{REQUEST_FILENAME} !-f
# Rewrite vervolgens alles naar index.php
RewriteRule ^/(.*)  index.php?url=$1

RewriteCond verwacht twee argumenten. De eerste is een variabele, de tweede een test op die variabele. Een uitgebreide uitleg over de beschikbare variabelen en tests is te vinden in de omschrijving van de directive van Apache.

Voorbeelden

Enkele praktijkvoorbeelden van het gebruik van mod_rewrite:

Alles herschrijven

Meestgebruikt in grote applicaties is de volgende methode: Alles wat niet bestaat wordt herschreven naar index.php. Op deze manier heb je volledige controle over wat je met welke URL doet, terwijl je nog steeds simpel de CSS-, JS-bestanden en plaatjes kan aanleveren. De URL hoeft niet te worden meegestuurd, aangezien die te vinden is in $_SERVER['REQUEST_URI']

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^                   index.php

www toevoegen

Deze code schrijft alles wat niet met 'www.' begint naar een domeinnaam mét 'www.'

RewriteCond %{HTTP_HOST} !^www\. 
RewriteRule ^.*$         http://www.domeinnaam.tld/$0    [R=301,L]

www weghalen

Deze code schrijft alles op 'www.domeinnaam.tld' om naar 'domeinnaam.tld'

RewriteCond %{HTTP_HOST} ^www.domeinnaam.tld$
RewriteRule ^.*$         http://domeinnaam.tld/$0        [R=301,L]

TODO uitleggen clean-url hint dat men neit gaat zitten klieren met duizend rewrite regels voor elke mogelijke URL die kan voorkomen, dat regel je beter in PHP.

Site Toolbox:

Persoonlijke hulpmiddelen
De laatste wijziging op deze pagina vond plaats op 17 mrt 2010 12:04. - Deze pagina werd 4.623 maal bekeken. - Disclaimers - Over PFZWIKI