Tutorials Books Videos Forums

Change the theme! Search!
Rambo ftw!

Customize Theme


Color

Background


Done

Clean URLs with Apache

by Miran Lipovaca aka foodpk   | filed under PHP and MySQL

This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.

In this tutorial, I'll show you how to switch from long URLs to short, clean URLs.
A basic understanding of how server-side languages work is recommended in order to
follow through.  Even though many websites are switching to clean URLs, most
websites that feature dynamically generated content use long URLs with query strings
in them, something like:

http://yoursite.com/index.php?cetegory=cooking&page=pasta&section=4

On the surface, you may be wondering what the real problem with that is. Sure, it doesn't look pretty, but does that really matter? It turns out, there are a few problems associated with such long, complicated URLs:

Because of those three reasons (and others I'm sure!) it's better to have concise, clean and descriptive URLs. At the end of this tutorial, you will learn how to take those huge URL's and make them cleaner. The clean URLs will look like static URLs, but via mod rewriting, you still trick them into getting data for generating dynamic content.

So with mod rewriting you can switch from URLs like:
http://yoursite.com/index.php?category=cooking&page=pasta&section=4

To something like:
http://yoursite.com/cooking/pasta/4

But the best thing is, you'll still receive the GET information from your query strings like you did before. It's a win-win situation!

Let's Get to Work!

So how do we go about doing that? First, make sure that you are allowed to set
per-directory .htaccess files. If you're not sure about that, ask your host. Next, create a file called .htaccess in the directory where your site is. We'll

assume that's the root (/) directory. That file should contain the following text:

Let's stop here for a bit and look at what the above does. First there are a few
commands that set things up for us. They tell the server to follow symlinks, turn
on the rewrite engine and set the rewrite base to /.

Note

If you have your site in one directory, say /mysite/ but want it to be accessed without that, like it was in the root, set the base to /mysite/ Otherwise, just leave it at /

Also, if your index.php is not in the root folder (/) modify the above rewrite rules accordingly. So if your index.php is in /mysite/, the first rewrite rule should have /mysite/index.php?category=$1 instead of /index.php?category=$1

Then are the rewrite conditions. That is where we tell the server that, if the URL
someone has tried to access is an actual file or a directory, don't interpret it
via the rules but just return it to the client. That's good because otherwise
we'd have some problems with links, images etc.

Phew! It's time to take a breather. In the next section, let's pick up from where we left off and discuss the rewrite rule itself.


In the previous section, you learned about the advantages of clean URLs, and we just got started explaining what the code you copied and pasted was. In this page, let's continue by learning about rewrite rules.

OK, so now comes the rewrite rule. A rewrite rule is comprised of a regular
expression (the request is matched against it) and if it matches, it gives the
client the file specified afterwards. Now I can't go about explaining regular
expressions as a whole, for that's a pretty hefty subject, but we'll take a glance at
what's done here.

If we take a look at the first rewrite rule:

RewriteRule ^([a-zA-Z0-9\-]+)/?$  /index.php?category=$1 [L,QSA]

it tells the server to match any character from a-z, A-Z, 0-9 and the dash - character. The + means it matches either 1 or many of those characters. Then there's a dash / and a question mark. A question mark after the dash means 'match either one or no dash at all'. The $ means the end of the line.

So the first regular expression basically says: "If something that's comprised of letters, numbers and the dash line, catch it. It doesn't matter if it has a slash afterwards or not."

Whatever we put in the parenthesis, we can use as a variable. After the regular
expression, we reach that variable by using $1, or $2 if it's the second variable,
and so on.

As you can now probably see, the first rewrite rule turns, say, http://yoursite.com/index.php ?category=cooking into http://yoursite.com/cooking (or http://yoursite.com/cooking/) Pretty, sweet, huh?

The second and third rule do the same thing, except they come to effect when someone
requests two 'directories', like http://yoursite.com/cooking/pasta. Then it gives
that person http://yoursite.com/index.php?section=cooking&page=pasta

In the example I've included the ability to read three 'fake directories' (so you can do http://yoursite.com/one/two /three), but if you need more, just add another
rewrite rule, I'm sure you can see what the pattern used is.

Note

The QSA in the [L,QSA] means that you can append query strings to the URL. So http://yoursite.com/cooking/
pasta/4/?show=something will work.

Clean URLs in Action

Below is a simple example of how to put all this mod rewriting to work. First put
the above .htaccess in the root folder. Then, use the following code as your index.php:

Let's say the user requests http://yoursite.com/aboutme. First the .htaccess will
interpret that and tell the server to call http://yoursite.com/index.php ?category=aboutme. Then the index.php will set $file to aboutme.php and check if it exists. If it exists, it will include aboutme.php into the page. If it doesn't, it will tell the user that tha page wasn't found.

The above was just a simple example, you can use what we learned here to get many
more variables (like http://yoursite.com/one/two /three) and then include them
however you want. Most of the time you will be including some of them while using
others to get stuff out of a database according to them.

One final note, if you have problems with links and images becoming broken after
using this, you should put a base tag in the head of your (X)HTML document, like so:

<base href="http://yoursite.com/" />

The base tag tells the browser where to begin looking when relative paths are in play.

If you have any questions regarding mod rewriting, feel free to ask them in the
forums!

High five!

miran lipovaca aka foodpk


Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy kirupa's books, became a paid subscriber, watch the videos, and/or interact on the forums.

Your support keeps this site going! 😇

The KIRUPA Newsletter

Thought provoking content that lives at the intersection of design 🎨, development 🤖, and business 💰 - delivered weekly to over a bazillion subscribers!

SUBSCRIBE NOW

Creating engaging and entertaining content for designers and developers since 1998.

Follow:

Popular

Loose Ends

:: Copyright KIRUPA 2026 //--