user11935130
user11935130

Reputation:

ErrorDocument 404 vs FallbackResource vs RewriteRule

By "copy-pasting" from the web without really understanding what's going on, I made my .htaccess file like this :

Options +FollowSymLinks -MultiViews -Indexes

ErrorDocument 404 /index.php?notfound=1  # (a)

FallbackResource /index.php?notfound=1  # (b)

RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [NC,QSA,L]  # (c)

I feel that (a) and (b) directives are not useful because of (c)... am I right ?

What's the real difference between those 3 directives ?

Upvotes: 1

Views: 2092

Answers (1)

C3roe
C3roe

Reputation: 96412

What's the real difference between those 3 directives ?

They all do more or less the same thing here.

ErrorDocument 404 and FallbackResource both set the given script as handler for anything that would otherwise cause a 404, because the requested URI does not map onto any existing file or folder.

I think the main difference here would be, that with ErrorDocument 404 you’d still get an entry in the server’s error log each time, whereas with FallbackResource it is considered implied that this is meant to be a front controller, so that won’t pollute your logs. If you needed any info about what actual 404s occured - then you would have to log them yourself from within your system, after it has determined that it actually did not find any content to serve under the requested URI.

The Rewrite version is basically just the “old school” version of that, the documentation for FallbackResource explicitly mentions that, https://httpd.apache.org/docs/2.4/mod/mod_dir.html#fallbackresource:

It is frequently desirable to have a single file or resource handle all requests to a particular directory, except those requests that correspond to an existing file or script. This is often referred to as a 'front controller.'

In earlier versions of httpd, this effect typically required mod_rewrite, and the use of the -f and -d tests for file and directory existence. This now requires only one line of configuration.

So with either of the first two, you don’t even need mod_rewrite to be available (which it sometimes might not be, on cheap shared hosting or something.)

The Rewrite version as shown above, would pass the originally requested URI under the parameter name url, so you have access to it using $_GET['url']. With either of the first two, it does not get explicitly passed in the new internally rewritten URL, so you have to access it from the server variables, as explained there a couple of lines further below,

A fallback handler (in the above case, /blog/index.php) can access the original requested URL via the server variable REQUEST_URI. For example, to access this variable in PHP, use $_SERVER['REQUEST_URI'].

Using mod_rewrite for things like this still has its uses, if you don’t want to rewrite all requests to the same script, or you don’t want to do the parameter parsing in PHP - like you might want to rewrite products/foo to products.php?product=foo and profile/username to profile.php?user=username.

ErrorDocument 404 and FallbackResource won’t allow for that in particular, mod_rewrite with different sets of rules that match these path segments specifically, could do that however.

I guess using FallbackResource would be considered state-of-the-art these days by most, and handling the parsing of the URL and deciding what needs to happen next based on that, is usually considered to be more logically placed in the scripting part of a site / application, rather than having this in a separate location, like .htaccess.

Upvotes: 3

Related Questions