Gillius's Programming

Removing php extensions in IIS with Ionic's Isapi Rewrite Filter

I was placed in a situation of updating and redeploying a PHP application on an older IIS 6 server. I have some small experience with PHP, but none at all with IIS (only Apache). One thing that I feel is very important that I know not everyone cares about is having clean URLs, or at least, removing the extension of dynamic pages. I don't know why a user to a website should have to see and know (when typing) whether my page is implemented in PHP, ASP, ASPX, JSP, or whatever. Typically I also like to remove .html as well, but actually I feel you can go either way on that one (because HTML is the content type the browser sees, not a backend). In this case the site was already moving URLs, and the long-term move away from PHP was also possible. I didn't want to risk having to break bookmarks again in the future.

Normally in Apache I would turn on MultiViews and also rely on default files like index.htm/php. While IIS 6 supports default files, it doesn't support MultiViews as far as I can tell. My searching didn't find much workarounds. I did find Ionic's Isapi Rewrite Filter though, which bascially is an open-source mod_rewrite for IIS. Read on for details on my configuration.

I couldn't get this to work as well as I wanted, or with the rules as clean as I wanted. I know there must be a better way, so I encourage comments, or contact me if you know of a better way. I did achieve all of my important requirements, though, for my specific application:

I allowed direct links with .php on the end to work, and I didn't redirect those to the "php-free" URL, but this is something I think is easily possible. Here is my configuration:

RewriteEngine ON
#uncomment this to enable the iirf status page (see documentation)
#StatusInquiry ON /iirfStatus RemoteOk

IterationLimit 5

# don't rewrite any request that ends with one of these extensions,
# even if they don't exist.
RewriteRule (.+\.)(jpg|png|jpeg|gif|ttf|sql|txt|zip|css)$   -   [L]

# If there is an exact match, then don't do any rewriting
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [L]

#If this is a URL ending with a /, try index.php, then index.html
#(I don't know how to get it to search as if we had done /index):
RewriteCond %{REQUEST_FILENAME}index.php -f
RewriteRule ^(.*)/$  $1/index.php [L]
RewriteCond %{REQUEST_FILENAME}index.html -f
RewriteRule ^(.*)/$  $1/index.html [L]
RewriteCond %{REQUEST_FILENAME}index.htm -f
RewriteRule ^(.*)/$  $1/index.htm [L]

# Try to see if this is a PHP page:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^/(.*)$  /$1.php [L]

# Try to see if this is an HTML page:
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^/(.*)$  /$1.html [L]
RewriteCond %{REQUEST_FILENAME}.htm -f
RewriteRule ^/(.*)$  /$1.htm [L]