How do I make all URLs run through a single PHP file?

How do MVC systems where the urls are in these forms force all the requests through a single index.php file?

http://www.example.com/foo/bar/baz
http://www.example.com/goo/car/caz/SEO-friendly-name-of-the-object
http://www.example.com/hey/you

EDIT: When I try the rewrite rules below I get this error:

[error] [client 127.0.0.1] Invalid URI in request GET / HTTP/1.1
[error] [client 127.0.0.1] Invalid URI in request GET /abc HTTP/1.1

EDIT: Oh, this is the complete content of /index.php. When I remove the rewrite rules, it outputs '/' or '/index.php' or I get a 404 for anything else.

<?php
echo htmlspecialchars($_SERVER['REQUEST_URI']);
?>

SOLVED: I added a / in front of index.php in the rewrite rule and then it worked:

SOLVED AGAIN: Turns out the / was only needed because I was running 2.2.4. When I upgraded to 2.2.11 the / was no longer needed.


Solution 1:

If you are using Apache, use rewrites via mod_rewrite:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]

This will rewrite your URLs to »index.php?q=foo/bar/baz« transparently.

The 2. and 3. lines tell the rewrite engine not to rewrite the URL if it points to an existing file or directory. This is necessary to have access to real files provided by the httpd server.

Solution 2:

The code below uses Apache's mod_rewrite to rewrite all URLs not pointing to a physical file or directory to be mapped to index.php. The end result will be:

http://www.example.com/index.php/foo/bar/baz
http://www.example.com/index.php/goo/car/caz/SEO-friendly-name-of-the-object
http://www.example.com/index.php/hey/you

Rewrite rule:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [PT,L,QSA]

Explanation:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Both the above lines dictate that this rule does not apply to regular files (-f) or directories (-d).

RewriteRule ^(.*)$ index.php/$1 [PT,L,QSA]

More information on how to create mod_rewrite rules can be gathered from the Apache web site: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html.