Hovednavigation

apache.jpg

Mod_Rewrite (module rewrite) er et modul i Apache webserveren. Modulet muliggør "omskrivning" af forespørgsler til serveren. Dvs. brugeren indtaster en URL men serveren sender denne forespørgsel videre til en anden fil. Dette ses bl.a. her på sitet, hvor man ved kontakt siden kommer ind på http://martin-nielsen.com/kontakt - det der så sker er, at serveren sender forespørgslen videre til http://martin-nielsen.com/index.php?navid=kontakt På den måde vil man på index.php stadig kunne modtage navid som GET variabel, og dermed kan vi stadig bruge almindelige includes.

I gang med mod_rewrite

Da dette er en introduktion, gÃ¥r vi ikke i dybden med mod_rewrite, men tager det fra bunden og stille og roligt. Trin 1 er at lave en .htaccess fil. Denne fil laver du i fx notepad, og nÃ¥r du gemmer skal du sÃ¥ huske, at vælge ”alle filer” i filtype – ellers vil filen blive gemt forkert. (NB husk punktummet foran htaccess.)

For at "starte" mod_rewrite skal den første linje i .htaccess filen være: RewriteEngine on

Efter mod_rewrite er startet, skal man give serveren instrukser, der fortæller den hvornår, og hvordan der skal redirectes, dette sker i følgende format:

RewriteRule Mønster Erstatning [Valgfrie tags]

Mønster

Vha. regular expressions angives hvornår mod_rewrite skal reagere (det ser vi nærmere på via eksempler om lidt)

Erstatning

Hvad skal der rewrites til

Valgfrie tags

Denne del er ikke nødvendig for mod_rewrite, men man kan nogle ekstra ting her, et par eksempler på nyttige attributter er

  • F - Forbudt - her vil brugeren simpelthen fÃ¥ en fejl 403 - not authorized
  • L - Last rule - Indikerer, at der ikke skal behandles flere regler i mod_rewrite efter denne
  • R[=code] - Brugeren bliver omstillet synligt, fx med koden 302 som er midlertidigt flyttet, eller 301 for permenent flytning af filen - rigtigt smart hvis man flytter sit site til et andet domæne
  • QSA - Querystring append - Hvis man ønsker, at kunne sende querystring variabler med pÃ¥ sin mod_rewrite

I gang med eksempler

Ovenstående virker måske en smule teknisk, og måske også et langt skridt fra den lovet introduktion, men det er rart nok lige at ha' lidt mere viden inden vi går i gang. Men nok om det. Første eksempel:


RewriteEngine on 
RewriteRule ^/([^/.]+)/?$ index.php?side=$1 [L] 

Første linje starter som sagt mod_rewrite. Dernæst har vi en rewriterule. for at gøre det nemmere gennemgår vi den stykke for stykke.

^
Checker om linjen starter med det efterfølgende - hvis ikke ignoreres regelen
([^/.]+)
( ) indikerer, at alt hvad der bliver matchet imellem parenteserne skal huskes. Inde i parenteserne har vi [^/.]+ Dette betyder i almindeligt sprog, match alt som ikke er en / eller et . (punktum) - (nb her er det vigtigt at . escapes med ). + tegnet indikerer at vi ønsker et eller flere tegn imellem.
/?$
$ indkikerer at det sidste der skal matches her vil være en mulig / (den er ikke nødvendig da den efterfølges af ?)
index.php?side=$1
Den side som der skal omskrives til internt, her bliver hvad vi har matchet mellem () indsat via $1 - hvis vi havde flere () sæt, ville disse blive $2 $3 osv osv.
[L]
Dette stopper mod_rewrite fra at udfører evt følgende rewrite regler

Herefter uploades .htaccess filen til rod biblioteket sammen med din index.php. Og i index.php vil du nu kunne modtage $_GET['side'] som min første tutorial gennemgik

Jeg vil også ha' undersider

Ja men ok da! Det skal du få, princippet er det samme, så jeg vil nøjes med et eksempel uden den store forklaring


 RewriteEngine on  
RewriteRule ^([^/.]+)/?$ index.php?side=$1 [L] 
RewriteRule ^([^/.]+)/([^/.]+)/?$ index.php?side=$1&underside=$2 [L] 

Her har vi simpelthen bare kopieret den første regel, og indsat en ekstra ([^/.]+) - og til slut sender vi det hele videre til index.php?side=$1&underside=$2

Betingelser

Du kan lave et hav af betingelser med mod_rewrite, men da målet med denne tutorial simpelthen er en grundlæggende ide om hvad man kan, holder vi os til det vigtigste. Som det er nu med eksemplet, vil alle mapper blive rewritet også, og det er jo ikke meningen, Derfor laver vi et check om det vi prøver at rewrite er en fil eller mappe:


RewriteEngine on  
RewriteCond %{REQUEST_FILENAME} -f [OR] 
RewriteCond %{REQUEST_FILENAME} -l [OR] 
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^.* - [L] 
RewriteRule ^([^/.]+)/?$ index.php?side=$1 [L]  
RewriteRule ^([^/.]+)/([^/.]+)/?$ index.php?side=$1&underside=$2 [L]

REQUEST_FILENAME indeholder det vi har indtastet i browseren, -f -L og -d checker alle om det er en fil, link eller mappe, hvis det er det stopper vi rewrite med -

HJÆLP min CSS, billeder osv virker ikke mere

Dette løber de fleste ind i. Dette skyldes, at browseren jo fx tror at /kontakt er en mappe, og den kan simpelthen ikke finde dine billeder og CSS filer inde i mappen /kontakt - Dette er nemt fixet, hvis dine billeder ligger inde i mappen images fx så sætter du bare / foran, dette vil fortælle browseren, at den skal lede efter images mappen, i roden af domænet, og vupti så virker det hele igen igen.

NYT: Har skrevet en række nye eksempler her: http://martin-nielsen.com/blog/nyttige_mod_rewrite_eksempler-182.html

Konklusion

Mod_rewrite kan lave dine URLs meget pænere, og mere semantisk korrekte, dette er ikke bare en fordel for dine besøgende, men også en fordel for dig, i forhold til søgemaskineoptimering mm. Du kan omskrive alt, det er kun fantasien der sætter grænser, fx lad os sige du driver en webshop hvor URLS måske ser sådan her ud: index.php?side=Produkter&katalog=Film&Genre=Action - kunne meget nemt ud fra denne introduktion omskrives til /produktkatalog/film/action - som sagt kun fantasien der sætter grænser! God fornøjelse.

Download eksempel

Vis eksempel

Apache mod_rewrite docs

The definitive guide to mod_rewrite (bog)

Flere eksempler

Relaterede blogindlæg

Del
Indlægget blev skrevet af Martin d. 12/02, 2007 kl 11:11 og blev sidst rettet d. 09/04, 2007 kl 10:10

Kommentarer

RSS Feed for dette indlæg

GravImg
Skrevet af Casper Hansen
30/04 - 2008 kl. 06:48

Så går jeg i gang med at læse, da jeg er ved at lave en ny blog og der skal bruges mod_rewrite :)

GravImg
Skrevet af Martin
30/04 - 2008 kl. 06:48

Ja men god fornøjelse :) - skal ha' skrevet en opfølgende guide til mod_rewrite, har bare ikke lige fundet tiden til det

GravImg
Skrevet af william
30/04 - 2008 kl. 06:48

hej.. ang. det med visning af billeder.. :) hvad mener du med at man \"bare\" skal sætte / foran... altså foran hvad ?

GravImg
Skrevet af Martin
30/04 - 2008 kl. 06:48

Hvis dit <img ser sådan her ud:
<img src="img/mitbillede.jpg">
ændrer du det til
<img src="/img/mitbillede.jpg">
samme med css stier og alle stier generelt, i det browseren vil tro den skal kigge i den falske mappe som rewriten jo egentlig er...
håber det gav lidt mening

GravImg
Skrevet af william
30/04 - 2008 kl. 06:48

Arghh okay!
prøver lige!

men hvis jeg henter fra en database... vil den stadigvæk forstå det?

GravImg
Skrevet af Martin
30/04 - 2008 kl. 06:48

du kan evt replace lidt på indholdet fra databasen fx med str_replace()

GravImg
Skrevet af Vayu
30/04 - 2008 kl. 06:48

Hej Martin.
Tusind tak for denne gode tut. Jeg har bakset med mod_rewrite i flere dage uden at finde en tut der kunne forklare enkelt og nemt hvordan det skal gøres. Sikke en lettelse!
Igen tak.
vh
Vayu

GravImg
Skrevet af Martin
30/04 - 2008 kl. 06:48

Så lidt, jeg sigter altid efter at gøre det så enkelt som muligt!

Regner med at skrive en fortsættelse til denne artikel i den nærmeste fremtid.

GravImg
Skrevet af Vayu
30/04 - 2008 kl. 06:48

Det bliver interessant at læse.
Har et spørgsmål. Jeg udvikler flere hjemmsider på en gang, og kan derfor ikke have flere index.php filer i roden på min localhost. Så f.eks. har jeg kopieret index.php og navngivet den default.php, men menu.php og style.css i en mappe der hedder "default". Ville det så ikke se ud som dette:
RewriteRule ^default.php/([^/.]+)/?$ default.php?page=$1 [L]
Det virker bare ikke. Hvor går det galt?
vh
Vayu

GravImg
Skrevet af Claus Fischer
30/04 - 2008 kl. 06:48

HÃ¥ber snart du kommer med en udvidelse. Jeg er en anelse forvirret.

GravImg
Skrevet af Claus Fischer
26/03 - 2008 kl. 21:50

Hvad er min fejl her??
RewriteRule ^forside([^/\.]+)/?$ index.php?p=$1 [L]

GravImg
Skrevet af Martin
30/04 - 2008 kl. 06:48

Kommer helt an på hvad du forsøger at opnå.
Den vil rewrite fx http://dinurl.dk/forsideblah til index.php?p=blah

Og arbejder faktisk på hele to mod_rewrite indlæg lige for tiden

GravImg
Skrevet af Claus Fischer
30/04 - 2008 kl. 06:48

Må jeg ikke se kilden koden i den htaccess fil du har i eksemplet? Jeg forstår simpelthen ikke hvor man skal skrive hvad den dynamiske url skal erstattes med?

GravImg
Skrevet af Claus Fischer
30/04 - 2008 kl. 06:47

http://www.X.dk/index.php?p=p1

Den ville jeg gerne oversætte til

http://www.X.dk/forside

GravImg
Skrevet af Martin
30/04 - 2008 kl. 06:48

.htaccess filen for eksemplet ligger i zippen http://martin-nielsen.com/downloads/mod_rewrite.zip

Men hvis det eneste du vil oversætte er den ene, altså ingen dynamisk match er det bare at lave en:
RewriteRule ^forside/?$ index.php?p=p1

GravImg
Skrevet af Claus Fischer
30/04 - 2008 kl. 06:48

Tak skal du have :)
Var lige det jeg ledte efter. Så havde jeg misfortået det helt.

GravImg
Skrevet af Claus Fischer
30/04 - 2008 kl. 06:48

Arh, sorry. Man må vidst ikke trykke opdater.

Ellers nogle lækre guides du laver.

Når man har postet en comment kan du så ikke lave sådan at man automatisk kommer ned og ser den? istedet for man skal bladre ned og se den eller for at se at den lavede fejl ved spam protection.

GravImg
Skrevet af Martin
01/04 - 2008 kl. 09:42

Flere eksempler kan ses her:
http://martin-nielsen.com/blog/nyttige_mod_rewrite_eksempler-182.html


Ny kommentar








Sikkerheds kode





DanskeWeblogs.dk | Samling af de danske blogs