Php – Mod_rewrite excluding files/directories but including .php files

.htaccessapache-2.2mod-rewritePHPregex

The traditional mod_rewrite for routing is as follows:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]

However I would like to add one extra condition which is that if a file exists (the -f flag) but that file has a .php extension the rewrite still goes ahead. There are a few ways I've tried to do this:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} (.php)$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]

Using an OR as well as a regular expression to find the .php at the end of the string. This doesn't work (i.e. it loads page.php instead of index.php)

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} .php$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /gadabouting.com/index.php [L]

A different form of the regex causes an Internal Server Error, but with no useful debug information (my current favourite thing to hate about software, poor quality error messages).

Examples:

domain.com/ -> domain.com/index.php
domain.com/string/ -> domain.com/index.php
domain.com/script.js -> domain.com/script.js
domain.com/string/string2 -> domain.com/index.php
domain.com/folder/file.php -> domain.com/folder/file.php
domain.com/file.php -> domain.com/index.php

I.e. for any file/path that does not exist OR any file in the root which contains .php the rewrite rule will be followed

Can anyone point out a rule which will correctly find a .php file and thus rewrite if it finds it in the FILENAME?

Edit: I just found a working solution which satisfies every example except #5. It rewrites any PHP file to index.php even if the file is in a sub directory. Attempts to resolve this have so far been unsuccessful, as the rewrite log doesn't show how it evaluates the RewriteCond directives.

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} .php$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !index.php
RewriteRule ^(.*)$ /gadabouting.com/index.php [L]

Best Answer

Assuming I'm understanding you, you only wish to rewrite .php files that are in the document root, something like this should do the job...

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} ^[^/]+\.php$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !index.php
RewriteRule ^(.*)$ /index.php [L]