6

I'm using a RewriteRule in .htaccess to redirect anything that is not an existing file, to a "cms.php" file which dynamically handles any request (or outputs some error message if appropriate).

Here's what I do in .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /cms.php [L,QSA]

Works like a charm.

However, for development purposes, I want to host the same site on my local XAMPP system as well. On my actual live webserver, the cms.php is right in de document root folder, hence I can use /cms.php there. But on my local development machine, this site is in some subdir, i.e. /cms.php is not the right path.

I also tried "cms.php" (without the / in front of it) as well as "./cms.php" (hoping that "." would denote the current dir) but to no avail. Only when I explicitly specify /the/correct/subdir/cms.php in the RewriteRule, it works OK, but obviously this is only valid on the development machine and not on my live webserver.

Can I somehow use a smart path or mod_rewrite variable or something, so that .htaccess understands it needs to redirect to my cms.php file in the same dir as where .htaccess itself resides ?

Sheldon Pinkman
  • 1,086
  • 4
  • 15
  • 21

1 Answers1

20

Typically, you'd just set a RewriteBase to the dev directory and leave the leading slash off of your rule's target:

RewriteEngine On
RewriteBase /subdir/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ cms.php [L,QSA]

But if that's not good enough, and you want to be able to move the htaccess file around arbitrarily without having to alter the base all the time, ou can try to do something crazy by detecting an arbitrary base:

RewriteCond %{ENV:URI} ^$
RewriteRule ^(.*)$ - [ENV=URI:$1]

RewriteCond %{ENV:BASE} ^$
RewriteCond %{ENV:URI}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=BASE:%2]

at the very top of your htaccess file, then using the BASE environtment variable:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}cms.php [L,QSA]
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • Hey thanks, it seems like a sophisticated approach, but I honestly have no idea what you're doing :) Could you please explain how this works? – Sheldon Pinkman Jan 14 '14 at 15:03
  • @SheldonPinkman for the first option, you're hardcoding the path in a `RewriteBase`, for the second option, you're extracting the base from the `%{REQUEST_URI}` by removing the relative URI from it (stored in the `%{ENV:URI}` variable). Then you can use this base as `%{ENV:BASE}`. – Jon Lin Jan 14 '14 at 15:47
  • Wow, I wasn't aware of such complex RewriteRules. Thanks a lot! Works like a charm. Never knew that "RewriteRule (condition) - [statement]" doesn't actually redirect anything, but just executes the statement. And the construction with the URI environment var (to get only the part relative to current dir) en then 'subtracting' that from REQUEST_URI is pretty clever. Kudos sir! – Sheldon Pinkman Jan 16 '14 at 09:54
  • Jon, great answer as always. Can you please refer to resources that could explain the `extracting the base from the %{REQUEST_URI} by removing the relative URI from it (stored in the %{ENV:URI} variable).` in a bit more depth. – Ejaz Jul 28 '16 at 23:21
  • This looks related http://stackoverflow.com/questions/37605218/what-double-colon-does-in-rewritecond – Ejaz Jul 28 '16 at 23:35
  • @Ejaz I wrote an [answer](https://stackoverflow.com/a/45244449) on another question which adds a bit more explanation to this. – aplum Jul 27 '17 at 21:27