ErrorDocument redirect in .htaccess when placed in subfolder

593 Views Asked by At

My development server (localhost) is setup so that each website is in it's own sub-folder, like so:

localhost
   \Site1
   \Site2

Each sub-folder (Site1, Site2 etc) has it's own .htaccess:

ErrorDocument 404 /alert.php?error=404
ErrorDocument 403 /alert.php?error=403
ErrorDocument 401 /alert.php?error=401

This works absolutely fine when on the live server (as it's then located in the website root location), however, in my localhost development environment, I have to update the htacess to:

ErrorDocument 404 /site1/alert.php?error=404

in order to make it work. This means a lot of updating the .htaccess back and forth when I want to test locally vs uploading for the live version.

Is it possible for the .htaccess to determine the correct path to use based on the host enovirnoment?

1

There are 1 best solutions below

0
MrWhite On

You could calculate the "base directory" (the directory in which the .htaccess file is located relative to the document root) using mod_rewrite and use this in the ErrorDocument directive with the help of an Apache expression (requires Apache 2.4.13).

For example:

# Calculate the BASE_DIR based on the location of the .htaccess file (rel to DocumentRoot)
# For use in the ErrorDocument directive the BASE_DIR does not include the slash prefix
# eg. If in the root directory then BASE_DIR = "" (empty)
#     If in /site1/.htaccess then BASE_DIR = "site1/"
RewriteCond %{REQUEST_URI}@$1 ^/(.*?)([^@]*)@\2
RewriteRule (.*) - [E=BASE_DIR:%1]

# Set ErrorDocument dynamically relative to BASE_DIR (Requires Apache 2.4.13+)
# The 2nd argument to the ErrorDocument directive must be prefixed with a slash
# in the source code itself for it to be interpreted as a local path.
ErrorDocument 404 /%{reqenv:BASE_DIR}alert.php?error=404

So, if the .htaccess file is located in the document root then the ErrorDocument is set to /alert.php?error=404 and if in the /site1 subdirectory then it's set to /site1/alert.php?error=404.

Aside: When using PHP you don't need to explicitly pass the error code to the alert.php script, since this is available in the $_SERVER['REDIRECT_STATUS'] superglobal. This also allows you to determine if the alert.php script was called directly.

HOWEVER, it would be preferable to define each site in it's own <VirtualHost>, with it's own DocumentRoot, rather than using subdirectories, and have exactly the same directory/URL structure for local development as on the live server - no messing. There are bound to be other places that are affected by the different path-depth, such as client-side links to static resources?