Redirecting all requests to index.php with .htaccess

Inspired by http://jrgns.net/redirect_request_to_index/.

The .htaccess file

# Enable rewriting.
RewriteEngine on

# Optional: do not allow perusal of directories.
Options -Indexes

# Optional: explicitly enable per-directory rewrites in the .htaccess context.
Options +FollowSymLinks

# Required when not in the webroot. Always use a trailing slash.
RewriteBase /

# To be able to access existing directories and files (standalone scripts).
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

# Redirect everything else to index.php.
# Add QSA to ensure that querystring variables are registered as such.
RewriteRule . index.php [L,QSA]

The index.php file

In the index.php we read the REQUEST_URI to determine the original URL the user called. We strip the path from the webroot so we end up with a cleaned (relative) path we can use to determine what content we want to load.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
// Read REQUEST_URI, suppress errors (gave E_WARNING prior to PHP 5.3.3).
$uriData = @parse_url($_SERVER['REQUEST_URI']);

$path '';
if ($uriData === false) {
    // Do something?
} else {
    if (isset($uriData['path'])) {
        // We might be in a subdirectory of the webroot.
        // We are only interested in the part starting from this relative root.
        $path str_replace(DIRECTORY_SEPARATOR'/'$uriData['path']);
        $relativePath str_replace(DIRECTORY_SEPARATOR'/'dirname($_SERVER['SCRIPT_NAME']));
        // Strip the relative path from $path.
        $path substr($pathstrlen($relativePath));
        // Finally, strip any leading/trailing slashes so we end up with a "cleaned" path.
        $path trim($path'/');
    }
}
?>

Now you can use $path in combination with, for example, a switch-statement or a database query to load certain content. You can use $_GET as before, just remember to filter input and escape output.

The above PHP code was written with readability in mind. If you want, line 10-17 can be abbreviated to the following:

1
2
3
<?php
$path trim(substr($uriData['path'], strlen(dirname($_SERVER['SCRIPT_NAME']))), '/');
?>

Todo