How to use rewrite rules using .htaccess in an aliased directory outside document root

Viewed 40

I am trying to use .htaccess to rewrite requests for PHP files that don't explicitly include the .php file extension (e.g. example.com/foo should rewrite to example.com/foo.php), but without applying that rule to any folders (or subfolders) of the document root.

My http.conf file contains following:

DocumentRoot "/webfiles"
<Directory "/webfiles">
  Options Indexes FollowSymLinks Includes ExecCGI
  AllowOverride All
  Require all granted
</Directory>

Alias "/exams" "/training/exams"
<Directory "/training/exams">
  Options Indexes FollowSymLinks Includes ExecCGI
  AllowOverride All
  Require all granted
</Directory>

DirectoryIndex index.php

There is a .htaccess file in the /training/exams folder containing following:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

The goal is to:

  1. serve requests like example.com/exams with /training/exams/index.php file,
  2. serve requests like example.com/exams/first with /training/exams/first.php file,
  3. while still having requests like example.com/myhome.html served with /webfiles/myhome.html.

Examples 1. and 3. work fine, but for 2. I get a 404 error.

1 Answers

Interesting question.

RewriteRule ^([^\.]+)$ $1.php [NC,L]

This ultimately ends up trying to rewrite the URL to /training/exams/first.php (after the directory-prefix is added back). I think that mod_rewrite (in a directory context) is seeing this as a URL-path and example.com/training/exams/first.php doesn't exist, hence the 404.

You can either use the RewriteBase directive to override the directory-prefix with the correct root-relative URL-path instead. For example:

RewriteBase /exams

Or, hardcode the URL-path in the RewriteRule substitution. For example:

RewriteRule ^([^.]+)$ /exams/$1.php [L]

(No need for the NC flag or to escape the literal dot when used in a character class.)

Or, use the REQUEST_URI server variable to construct a root-relative URL-path:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
Related