Til Top

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:

Kopier til udklipsholder | Vis uden linie #
01 RewriteEngine  on  
02 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

Kopier til udklipsholder | Vis uden linie #
01  RewriteEngine  on    
02 RewriteRule  ^([^/.]+)/?$  index.php?side=$1  [L]  
03 RewriteRule  ^([^/.]+)/([^/.]+)/?$  
04 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:

Kopier til udklipsholder | Vis uden linie #
01 RewriteEngine  on    
02 RewriteCond  %{REQUEST_FILENAME}  -f  [OR]  
03 RewriteCond  %{REQUEST_FILENAME}  -l  [OR]  
04 RewriteCond  %{REQUEST_FILENAME}  -d  
05 RewriteRule  ^.*  -  [L]  
06 RewriteRule  ^([^/.]+)/?$  index.php?side=$1  [L]    
07 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

kommentarer

Skrevet d. 26. Marts 2008 21:50 af Claus Fischer
Bruger billede Hvad er min fejl her??
RewriteRule ^forside([^/.]+)/?$ index.php?p= [L]
Skrevet d. 1. April 2008 09:42 af Martin
Bruger billede Flere eksempler kan ses her:
http://martin-nielsen.com/blog/nyttige_mod_rewrite_eksempler-182.html
Skrevet d. 30. April 2008 06:47 af Claus Fischer
Bruger billede http://www.X.dk/index.php?p=p1

Den ville jeg gerne oversætte til

http://www.X.dk/forside
Skrevet d. 30. April 2008 06:48 af Martin
Bruger billede Ja men god fornøjelse :) - skal ha' skrevet en opfølgende guide til mod_rewrite, har bare ikke lige fundet tiden til det
Skrevet d. 30. April 2008 06:48 af Vayu
Bruger billede 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
Skrevet d. 30. April 2008 06:48 af Casper Hansen
Bruger billede 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 :)
Skrevet d. 30. April 2008 06:48 af william
Bruger billede hej.. ang. det med visning af billeder.. :S hvad mener du med at man "bare" skal sætte / foran... altså foran hvad ?
Skrevet d. 30. April 2008 06:48 af Martin
Bruger billede 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
Skrevet d. 30. April 2008 06:48 af william
Bruger billede Arghh okay!
prøver lige!

men hvis jeg henter fra en database... vil den stadigvæk forstå det?
Skrevet d. 30. April 2008 06:48 af Martin
Bruger billede du kan evt replace lidt på indholdet fra databasen fx med str_replace()
Skrevet d. 30. April 2008 06:48 af Martin
Bruger billede 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.
Skrevet d. 30. April 2008 06:48 af Vayu
Bruger billede 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= [L]
Det virker bare ikke. Hvor går det galt?
vh
Vayu
Skrevet d. 30. April 2008 06:48 af Claus Fischer
Bruger billede Håber snart du kommer med en udvidelse. Jeg er en anelse forvirret.
Skrevet d. 30. April 2008 06:48 af Martin
Bruger billede 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
Skrevet d. 30. April 2008 06:48 af Claus Fischer
Bruger billede 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?
Skrevet d. 30. April 2008 06:48 af Martin
Bruger billede .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

Skrevet d. 30. April 2008 06:48 af Claus Fischer
Bruger billede Tak skal du have :)
Var lige det jeg ledte efter. Så havde jeg misfortået det helt.
Skrevet d. 30. April 2008 06:48 af Claus Fischer
Bruger billede 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.

skriv kommentar

Felter markeret med gult og * er påkrævet







Sikkerheds kode


Pingbacks

Hvis du linker til en af mine blog artikler fra et blogsystem der udsender pings vil du få et gratis do-follow link fra mig, du kna også twitte om en post og få et link til din twitter profil (Jeg forbeholder mig dog retten til at slette eller nofollow spam :P)