Route Everything through Index.php With Mod_rewrite

In this Tutorial, it is shown how to redirect all HTTP requests to a index.php file using htaccess or Apache configuration files.

2462 views
d

By. Jacob

Edited: 2023-09-10 23:02

Apache tutorial

To rewrite all requests to PHP we may use .htaccess, or better yet, the Apache configuration files.

You can often find the Virtual Host configuration files in /etc/apache2/sites-available, and the code should be added to your directory block.

Personally I prefer to use the Apache configuration files on a live server, and possibly .htaccess on a local test server. It will be easier to edit .htaccess files in your IDE, and you do not have to reload or restart Apache to apply changes.

To redirect everything, except for files that exist, we may use the following:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [QSA,L]
To redirect everything, including files that exist:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ index.php [QSA,L]

Note. The dash "/" in front of index.php is not needed, and it is also not necessary to specify a DirectoryIndex when using these rules.

Redirecting everything to PHP

It is important to understand, you will not actually be "redirecting" requests. What you are doing is known as "rewriting", which simply maps HTTP requests to certain local files, in this case a server-sided PHP script file.

It is actually quite common to redirect everything to PHP, possibly with the exception of static files. However, there are also good reasons to redirect static files.

Delivering static files through PHP gives us better control over caching headers, and also allows us to support the range request header. Including a accept-ranges response header both allows for pausing and resuming downloads, as well as the use of video controls when playing video files.

Another benefit is that it will be easier to put content behind a login, even preventing access to content if you got the direct link.

There probably is a small performance hit from calling PHP on every request, which is why we might want to leave some resources in a "public" directory and let those be handled by the web server directly. However, even if everything is handled by PHP, it should be mentioned that performance is not of any significant concern in most cases. In fact, you might even see performance gains due to proper use of caching headers.

It is always a good idea to support caching, even on HTML pages that are generated by PHP. Another common tactic is to save a copy of the HTML that is generated by PHP, and then serve it up for as long as the content has not changed. This can significantly speed up a website, and is a very effective way to optimize even the slowest CMS.

Using mod_rewrite

The first way to deal with rewriting is taken from the mod_rewrite documentation, under the Fallback Resource section:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [QSA,L]

This tells Apache to rewrite all URLs that does not correspond to a file or directory that exists. Obviously, controlled by the !-f and !-d rules respectively. But, what if you want to pass everything to PHP? As it turns out, you can not simply remove the RewriteCond's, as that will unintuitively result in a 500 internal server error.

Instead, you have to do resort to crazy hackery like:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ index.php [QSA,L]

Yet, the first example might actually be best, since it will allow Apache to still serve up some static files. If you use php-fpm, you might want to combine this with ProxyErrorOverride to enable custom error pages.

Finally, to be totally clear about everything, the QSA part means that query strings should be appended, while the L flag means that it should be the last rewrite rule to process. The regular expression is pretty basic, and similar to how you would write a regex in PHP and other contexts.

Links

  1. Fallback Resource

Tell us what you think:

  1. Understanding file permissions in Unix / Linux based systems, and how to make files immutable.
  2. In this article I will explain how to enable a swapfile on small instances, and why it might be useful, even if you do have enough physical memory.
  3. How to determine an optimal value for pm.max_children and related php-fpm settings for your server and web applications.
  4. Tutorial showing how to configure a VirtualBox Guest VM with HOST-only and NAT adapter, while using the WWW folder from the HOST OS.
  5. You may have wondered what the /etc/php/8.0/conf.d/ directory is for in Debian and Ubuntu, and whether it is better to edit the conf.d files than editing php.ini directly; find out in this Tutorial.

More in: Linux servers