Pretty Permalinks on IIS
A workaround for WordPress permalinks on a Windows server
Today I needed to optimise a WordPress-driven website for SEO reasons. First thing to do was to enable pretty permalinks, but the website was hosted on a Windows server using IIS 6.0. The best I could obtain out-of-the-box is a permalink structure like this one:
http://www.my-domain.com/index.php/2009/09/21/my-pretty-permalink/
This is better than appending post IDs in the querystring, but is still far from perfect, as it includes the ‘index.php’ string in the URL.
I googled around for possible solutions and workarounds and found this useful article. This worked pretty good, but unfortunately didn’t cater to existing permalinks. In other words, using permalinks like the one above resulted in 404 errors.
I modified the PHP code slightly to add support for existing permalinks (with ‘index.php’ in them), so the blog can use pretty permalinks, but old posts linked elsewhere with ugly permalinks work too.
Source code:
<?php
// This is the default file for the site. Usually index.php
$default = 'index.php';
// The name of this file.
// Set this value for the URL in Custom Error Properties of your website in IIS.
// Goto: IIS Manager > Websites > [Site Name] > Properties > Custom Errors >
// 404 & 404;2 & 404;3 > URL (Requires a '/' prefix in IIS).
$thisfile = '404-handler.php';
$_SERVER['ORIG_PATH_TRANSLATED'] = str_replace($thisfile, $default, $_SERVER['ORIG_PATH_TRANSLATED']);
$_SERVER['SCRIPT_FILENAME'] = str_replace($thisfile, $default, $_SERVER['SCRIPT_FILENAME']);
$_SERVER['ORIG_PATH_INFO'] = str_replace($thisfile, $default, $_SERVER['ORIG_PATH_INFO']);
$_SERVER['SCRIPT_NAME'] = str_replace($thisfile, $default, $_SERVER['SCRIPT_NAME']);
$_SERVER['PHP_SELF'] = str_replace($thisfile, $default, $_SERVER['PHP_SELF']);
$_SERVER['PATH_INFO'] = false;
$qs =& $_SERVER['QUERY_STRING'];
$ru =& $_SERVER['REQUEST_URI'];
// Fix for existing permalinks (eg. http://www.my-domain.com/index.php/2009/09/21/my-pretty-permalink/)
if(strpos($ru,'/'.$default.'/',0)) $ru = str_replace('/'.$default.'/','',$_SERVER['REQUEST_URI']);
$pos = strrpos($qs, '://');
$pos = strpos($qs, '/', $pos + 4);
$_SERVER['URL'] = $ru = substr($qs, $pos);
$qs = trim(stristr($ru, '?'), '?');
// Required for Wordpress 2.8+
$_SERVER['HTTP_X_ORIGINAL_URL'] = $ru;
// Fix GET vars
foreach ( $_GET as $var => $val ) {
if ( substr($var, 0, 3) == '404') {
if ( strstr($var, "?") ) {
$newvar = substr($var, strpos($var, '?') + 1);
$_GET[$newvar] = $val;
}
unset($_GET[$var]);
}
break;
}
include($default);
?>
While I know this is just a workaround, this seems to have solved my problem and works pretty good so far.
If anyone knows of better solutions, comments are welcome!
2 Comments | View
Come on, leave your feedback!