http://example.com/index.php?type=article&id=25&date_written=20020322.What I call "clean" URLs is what you can see on evolt.org, for instance. In my example the URL would be:
http://example.com/article/200203226. Let us assume that this article was the 6th written on the 22nd of march, 2002 and that we store this info in our database, see below, Structuring your data). The purpose of this article is to show you how to switch from the former to the latter with Apache and PHP through a simple example.Note: there's nothing polemic about this "clean" qualification. Anybody who finds a better name is welcome to use it instead...
index.php?style=red? How can one expect a search engine to know the difference?
idyou must think of a unique, not-to-be-changed-in-the-future identifier.My method in our example is this: create a field
uniqidand give it the date concatenated with the rank of creation within the day. In my example my article's
200203226(the article was the 6th created on the 22nd of March, 2002). Of course one can imagine a situation where only one article is written per day. Thus maybe this
uniqidfield is redundant if you store the date the article was written. Or it can be YYYYMMDDHHmmss to have the whole date and no rank. [insert here any other naming method you like].Note: there are many other ways to store your articles. Maybe they're each in their own text file in a dedicated
includesdirectory and then you call them through an inclusion, maybe they're extracted from an XML file, etc. That's why I'm not too specific on the storage of data here.
articlefile using standard PHP code, even if, as you noticed, the file has no
.phpextension. We'll come back to this issue below, in Using Apache's ForceType. Here's the code for our
<?php /* 1. parse the URL */ $expl = explode("/",$HTTP_SERVER_VARS["REQUEST_URI"]); $article_id = $expl[count($expl)-1];
/* 2 security check */[omitted for the sake of simplicity]
/* 3 populate the page with uniqid's content */[omitted for the sake of simplicity]?>
Here's how it works:
REQUEST_URI) by exploding it, fetch the results in an array (
$expl) and assing to
$article_idthe last occurence of the explosed array.
$article_idis not correct. In particular we'll check the following:
$article_idvalid? Does it really correspond to the format I'm looking for? For instance if I'm looking for a number of the form 'YYYYMMDDr' ('r' is the 'rank' in my example, remember?) and
$article_idis a string (ie. 'foobarwhatever'), then there's something rotten in the kingdom of URLs.
$article_idcompare to an existing value of
$article_idthat could damage the database? Think of
drop tableinstructions, for example.
ForceType. This Apache directive forces the server to consider a file as being of another type than what is expected by default (see Apache's documentation on ForceType).We will now use the
<FilesMatch>directive to specify which file is to be considered as a PHP file and not a plain ol' text file, which is the default on most servers (see Apache's documentation on <FilesMatch>).Don't worry: even if you can't configure Apache directly because your hosting provider doesn't allow it, I've got good news: you can do it through a
.htaccessfile.Here's a sample
.htaccessI wrote in my root directory:
<FilesMatch "^article$"> ForceType application/x-httpd-php</FilesMatch>The result is: Accessing
http://www.example.com/article/200203226tells the server to consider
articleas PHP, then parse the URL, and push the content whose
200203226into the template. And voilà. We're done.
ForceType'd pages so that all the formatting will be written only once. You can also, like often in evolt.org, create longer URLs and parse them as a set of several parameter/value pairs. Be careful with that, though, because you may force search engines to index too many occurences of pages. Oh, well, maybe that's what you want after all...