Sysadmins of the North

Technical blog, where topics include: computer, server, web, sysadmin, MySQL, database, virtualization, optimization and security

How to hide the .php file extension with IIS URL Rewrite Module

How to hide the .php file extension with URL Rewrite on Windows Server IIS? Sometimes it’s important to hide the file extension of scripts you use. Security by obscurity might be that reason, if you don’t want others to know what script language you are using for your website. This example will hide the .php extension using the IIS URL Rewrite module, in a ready to use web.config & .htaccess example.

Why hide file extensions in URL’s?

Security by obscurity is one reason to hide the file extension in URL’s, if you don’t want others to know what script language you are using for your website. Search Engine Optimization (SEO) is another valid reason, or perhaps you just want to hide the file extension for no apparent reason.

I am no fan of security by obscurity, and I have never encountered this as the result outcome or requirement in a security scan.

You can however, use this technique to shorten URL’s a bit. It does shave off four to five characters from the URL (“.php”, “.html”, “.aspx”). And some say a website performs faster because a web server can match URL’s without extensions to folders (directories) faster than URL’s with an extension to a file.

Unfortunately I have no data or further information on this.

Hide .php extension with URL Rewrite on IIS

This technique is also known as Multiviews or Content Negotiation in Apache. See below for an example to use with .htaccess in IIS.

This may interest you:   KMS Migration from 2008 R2 to Windows Server 2012 R2 and KMS Activation Known Issues

MultiViews, or content negotiation:

The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client’s requirements.

Here is an IIS URL Rewrite example for you.

Put the following rewrite in a web.config file to hide the .php extension in your URL’s. Well, the example doesn’t really hide .php from the URL, but this allows you to use extension-less URL’s like www.example.com/index.

URL Rewrite adds the .php part to the URL in the background.

<rewrite>
  <rule name="hide .php extension" stopProcessing="true">
    <match url="(.*)" />
      <conditions>
      <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
      <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
    <action type="Rewrite" url="{R:1}.php" />
  </rule>
</rewrite>

Hide extension for requests already containing a .php extension

A more extended example is to redirect all requests with .php the URL to their extension-less variant. So when a visitor comes in through /index.php, the extension is stripped and he will be directed to /index.

Our Rewrite rule maps that final request back to index.php without displaying the extension.

<rewrite>
  <rules>
    <rule name="Redirect .php extension" stopProcessing="false">
      <match url="^(.*).php$" ignoreCase="true" />
    <conditions logicalGrouping="MatchAny">
      <add input="{URL}" pattern="(.*).php$" ignoreCase="false" />
    </conditions>
      <action type="Redirect" url="{R:1}" redirectType="Permanent" />
    </rule>
    <rule name="hide .php extension" stopProcessing="true">
      <match url="^(.*)$" ignoreCase="true" />
    <conditions>
      <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
      <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      <add input="{REQUEST_FILENAME}.php" matchType="IsFile" />
    </conditions>
      <action type="Rewrite" url="{R:0}.php" />
    </rule>
  </rules>
</rewrite>

Always test such examples before putting it into production.

This may interest you:   Tunnel RDP through SSH & PuTTY

Emulate Apache Multiviews in IIS using a .htaccess file and Helicon Ape

If you use .htaccess in IIS you can create the same Multiviews effect to hide the .php extension.

For this to happen you have to declare a few rewrite conditions and rewrite rules (RewriteCond and RewriteRule).

The neat part is, this should also work with Linux, Apache and mod_rewrite, making this solution cross-platform!

Multiviews .htaccess example
In your .htaccess file, add the following rewrite configuration:

# Enable the Rewrite Engine
RewriteEngine On

# Match a folder name, www.example.com/dev/ in this case
RewriteBase /dev/

# SEO URL's for PHP files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Hide the .php extension to prevent double content
RewriteRule ^(.+).php$ $1 [NC,L,R=301]

# Rewrite to, and present the contents of the .php files, 
# if there is no file extension in the URL.
#   For example: /foo shows /foo.php
RewriteRule ^([^/]+)(?:/(.+))?$ $1.php?(?2p=$2) [L]

.htaccess rules explanation:
The first code block uses two RewriteCond checks to verify whether or not the URL is a file or folder. This is more complete, clear and faster than to create an exception for every file type possible.

The RewriteRule rewrites the URL – that mostly doesn’t contain a file extension – to a PHP file with that name.

The pattern ^([^/]+)(?:/(.+))?$ is explained as follows:

  1. The enclosing characters ^ and $ mark the beginning and end of the string; which prevents the rule from sometimes matching only a portion of the URL
  2. The group ([^/]+) matches the name of the PHP file as $1. And it finds all the characters up to a slash, or the end of the string
  3. The block (?:/(+).)? tries to find a slash, followed by other characters, and saves it as $2

The replacement $1.php?(?2p=$2) uses a conditional reference:

  • The query string is filled with p=$2 if $2 exists.
This may interest you:   Hyper-V Quick Create: run Ubuntu virtual machines even easier

Finally, a rule is added that hides the .php extension.

This prevents a search engine from finding duplicate content, and thus prevents a penalty for your site’s position in the search results.

There are other ways too.

Remove .php extension with .htaccess from URLs

To remove the .php extension from a URL with .htaccess, you can save the following in a new .htaccess file:

<IfModule mod_rewrite.c>
RewriteEngine on

# Redirects example.com/file.php to example.com/file properly
RewriteCond %{REQUEST_FILENAME} !-d         # is not directory
RewriteCond %{REQUEST_FILENAME}\.php -f     # is an existing html file
RewriteCond %{REQUEST_URI} ^(.+)\.php$      # request URI ends with .php
RewriteRule (.*)\.php$ /$1 [R=301,L]        # redirect from index.php to index
</IfModule>
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

Or use MultiViews:

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

This removes the extension making the URLs more user and SEO search engine friendly. Use what works best for you, and add a canonical meta tag in your HTML head to avoid duplicate content (where appropriate).

4 Comments

  1. Hi, I was looking for this & have implemented the same code for my website. It is a simple website with .html extension. I personally do not like the extension to be shown in browser so I applied the code in web.config file and it is working perfectly. Thank you for great knowledge sharing

    • Hi Froggy,

      Thank you for your reply, great to hear it works perfectly in your web.config file.

      Coincidentally, one of our customers uses the following URL rewrite:

      <rewrite>
          <rules>
              <rule name="Rewrite content">
                  <match url="^([_0-9a-z-]+)" />
                  <conditions logicalGrouping="MatchAll">
                      <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                      <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                  </conditions>
                  <action type="Rewrite" url="{R:1}.html" />
              </rule>
          </rules>
      </rewrite>
      
  2. Excellent :) thanks!!

  3. Thanks for your comment.

    Removing the .php extension is sometimes known as “Apache multiviews”. I’ve created a post back in 2011 about this (in Dutch), for use with Helicon ISAPI Rewrite or Ape in .htaccess files and IIS URL Rewrite (web.config) on Windows Server: [snip URL, the post is now incorporated into this one].

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

yGMVLUmSL M