mod_rewrite

chris (2004-05-01 19:53:54)
6655 views
4 replies
It's been a while since I posted here, but seeing as I have just put the first major update into the channels this year, I'll document how it was done:

A very basic introduction to Apache and mod_rewrite

I wanted mod_rewrite to make the url strings more user-friendly and also to make the site more search-engine friendly.

The result is what you see in the address bar of your browser. The url is free of appended query data.

The address of this page is actually showpost.php?id=121, but I have some simple url rewriting rules built into my apache web server. The process was as simple as this:

1) assuming you have already dowloaded your sources from apache.org and extracted them into a convenient location, now configure your apache build as follows:
./configure --with-layout=Apache --enable-module=so --enable-module=rewrite

add any other directives you require for mod_ssl or mod_perl or whatever, then make && make install.

2) Open up your httpd.conf file into your favourite text editor and add the following:
RewriteEngine   On

<Directory />
    RewriteBase /
    Options FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
<Directory /export/spiration/www/>
    RewriteBase /export/spiration/www/
    Options FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

The only addition to these sections is the line which reads "RewriteBase /path/location"

Now in the VirtualHost section of the site which you want to apply rewrite rules to, provide statements similar to the following:
        RewriteRule ^/post/(.*)   /showpost.php?id=$1
        RewriteRule ^/profile/(.*)   /showprofile.php?id=$1

So in the first case, the actual location of the script is /showpost.php, but I'm telling apache to find any links which look like ^/post/(.*) and then to rewrite them to /showpost.php?id=$1, which is the script which actually has to run.

So you see what's coming up next?

3) edit your html sources:

Well if there's an easier way to do this, then let me know, but my next job (and it took an evening) was to go through all the sources of my php-driven site and change all the links to be the user-friendly version (which will now be rewritten by the mod_rewrite engine whenever they are requested to give the real link). So whenever I saw the link href='showprofile.php?id=$profile' I had to recode that to say: href='profile/$profile'

4) regular expressions
You will need to understand basic regular expressions (regexps) to achieve this, becase the Rewrite directives in the http.conf require expressions to match the links they describe, so in the statement:
        RewriteRule ^/post/(.*)   /showpost.php?id=$1
the ^ matches the start of the expression, the .* matches anything and the brackets are used to capture the 'anything' into variable $1, which is then interpolated back into the rewritten URL (/showpost.php?id=$1).

4) Comments
I'd like to hear your comments and experiences, so please reply to this post and let's hear what you have learned about mod_rewrite.

cheers,
christo

comment
azz0r
2004-05-09 21:53:36

Cool article

Very informative, personally I have to use multiviews because mod_rewrite isnt as dynamic as id like.

Sure someone would find this useful thought :)
reply icon
anonymous
2005-02-18 17:36:52

Apache2 Mod_Rewrite

For Apache2, I use:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/images/.*
RewriteRule ^/([a-zA-Z]+)/$ /file.php?node1=$1
RewriteRule ^/([a-zA-Z]+)/([a-zA-Z]+)/$ /file.php?node1=$1&node2=$2
RewriteRule ^/([a-zA-Z]+)/([a-zA-Z]+)/([a-zA-Z]+)/$ /file.php?node1=$1&node2=$2&node3=$3
</IfModule>

Line 3 turns off redirects for the "images" folder.
Lines 4-6 send folder names to $_GET variables.

It sure beats maintaining/uploading a deep and complicated folder structure.
reply icon
DanDev
2008-02-08 16:09:33

Typo

--enable-module-rewrite
should read
--enable-module=rewrite

reply icon
chris
2008-02-08 22:24:29

--enable-module-rewrite
should read
--enable-module=rewrite



fixed - and added 'code' blocks too for readability.

ta
christo
reply icon