February 17, 2011

URL Rewriting On IIS/PHP Using PATH_INFO

IIS does not directly support URL rewriting. For this purpose you need extensions such as Helicon Tech ISAPI Rewrite, Ionic's Isapi Rewrite Filter or URL Rewrite Module for IIS 7.0. Without such extensions, PHP applications that capitalize on URL rewriting may work on IIS with not-so-clean URLs; or may not work at all. Yet some versatile applications can use PATH_INFO style clean URLs when mod_rewrite or its equivalent functionality is not available.

In the following article I will show you how to test and fix your PHP installation to make URLs containing PATH_INFO work as expected.

Verify that PHP is setup correctly

To verify if PHP is setup correctly for PATH_INFO, create a file containing these lines:

<?php
phpinfo();
?>

and save this file as "phpinfo.php" inside the root directory of your IIS website. Now open http://localhost/phpinfo.php/pathinfo-test in your web browser to view the result.

If everything is good, the phpinfo page should appear. Verify that the page contains the variable _SERVER["PATH_INFO"] with the value /pathinfo-test.

Configure Script Mapping

If you get a 404 error page when testing the above-mentioned script, you need to make a minor change to the IIS script mapping. Most PHP on IIS installation tutorials (such as the one I wrote) tell you to activate the "Verify that file exists" option while creating the script mapping.

With this setting enabled, IIS will check for the presence of the file before invoking PHP executable (fastcgi.dll or php-cgi.exe). Therefore a URL that refers to a PHP script that does not exist will cause IIS to return a 404-File not found error. But at the same time, a URL that refers to a valid PHP script followed by PATH_INFO will also cause IIS to send the 404 error; which is not what we want.

To work around this, de-activate the "Verify that file exists" option and IIS will fire PHP for all URLs that end with ".php" or contain ".php/". The flip side is that that you will see a "No input file specified" error instead of the usual IIS-generated 404 error when the requested PHP script does not exist.

To configure the script mapping on IIS follow these steps:

  1. Launch Internet Information Services Manager (run inetmgr.exe).
  2. Expand the nodes in the left hand pane and locate Web Sites.
  3. Right click on Web Sites and select Properties item on the context menu.
    • Note: If the script mapping does not propagate to the child web sites, repeat the following process for each web site below the Web Sites node.
  4. Switch to Home Directory tab.
  5. Click the Configuration... button.
  6. Click on the .php entry in the Application Mappings list and click the Edit... button.
  7. Un-check the Verify that file exists check-box.
  8. Close all dialog boxes by clicking OK.

Configuring Applications

I will now show you how to configure some PHP applications on IIS that can utilize PATH_INFO to generate clean, search engine friendly URLs.

Configure CakePHP on IIS

CakePHP is an open source web application framework for producing web applications. An out-of-the-box installation of CakePHP on IIS will work with query string URLs. Those that fail to realize this end up getting a couple of 404 errors and give up.

Lets begin with a clean installation of CakePHP. Download latest version of CakePHP and extract the contents in a suitable location on your IIS server. Lets assume that CakePHP is available at http://localhost/cakephp/. Open this URL in your web browser and you should see a page similar to this:

CakePHP on IIS - Before configuration

You should be able to see the same page at http://localhost/cakephp/index.php?url=/pages/home. Notice that this page does not display the logo and stylesheet correctly. Before we continue, correct the problems regarding write permissions, security settings and database configuration.

Now edit the /app/config/core.php and un-comment the following line:

Configure::write('App.baseUrl', env('SCRIPT_NAME'));

Optionally, delete the /.htaccess, /app/.htaccess and /app/webroot/.htaccess files.

You have now turned on CakePHP pretty URLs that utilize PATH_INFO instead of .htaccess style URL rewriting. Load http://localhost/cakephp/ in your web browser again and you should see a page similar to this:

CakePHP on IIS - After configuration

You should also be able to access the same page at the following URLs:

  • http://localhost/cakephp/index.php?url=/pages/home (query string URL)
  • http://localhost/cakephp/index.php/pages/home (pretty URL)

Properly written CakePHP applications are supposed to generate the correct URLs automatically depending on the above-mentioned setting; so there is not much for you to worry about. You can now go ahead and download the CakePHP applications of your choice and configure them as described above. Or get started by following instructions in the 15 minute blog tutorial.

Configure WordPress on IIS

WordPress is a PHP+MySQL powered open source Content Management System used to create generic websites or blogs. A quick and dirty WordPress installation goes something like this:

  1. Download latest version of WordPress
  2. Extract the contents in a suitable location on your IIS server. Lets assume that WordPress is available at http://localhost/wordpress/.
  3. Rename the /wp-config-sample.php file to wp-config.php.
  4. Edit this file and fill in the database details and security keys
  5. Run the WordPress installation script by accessing http://localhost/wordpress/wp-admin/install.php in your web browser.

Once you complete the installation you will be asked to log in to the admin section. Do so and navigate your way to the Settings > Permalink Settings section. You will notice that this section lets you choose from various types of PATHINFO style Almost Pretty permalinks that contain /index.php/:

Wordpress permalink setting

Note that on IIS6 and 7, WordPress might also let you to choose from mod_rewrite style Pretty permalinks. In order to use them you need special IIS setup, components and configuration. Explaining this is beyond the scope of this article.

Choose any permalink style of your choice and save changes. Now navigate to http://localhost/wordpress/; click on the Hello World post and you will end up with a URL similar to http://localhost/wordpress/index.php/2011/02/hello-world/.