Sam's infrequently-updated cabinet of curiosities
Wednesday, 19 January 2005

PHP-CGI "No input file specified" fix

Dreamhost prefers users to run PHP as CGI program rather than as an Apache module, for security reasons. I'm totally fine with this, but it has some drawbacks. The only one I've actually noticed is that it utterly breaks custom 404 pages. I think this is fixed in PHP 5, but it's still in whatever version this server is running.

The server doesn't spring a 404 error because it's just passing the requested filename as a parameter to php.cgi, wherever it may reside. When it can't find the file, it responds with its own error message:

No input file specified

If you've gone to the trouble to set up custom pages in your site style, it's more than a little annoying to have them replaced by something so utterly useless, unhelpful, and downright confusing.

But now, I notice, someone's posted a solution! It's a clever bit of mod_rewrite hackery.

RewriteEngine on
Rewritecond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule \.php$ /404.html

!-f checks to see if the requested .php location exists and is a real file. If not the rewrite rule will direct to the chosen error document. The only real drawback I can see is that it'll mess with requests for things other than real files -- notably, symlinks.

It's also not perfect if you have a single error.php file, and use $_SERVER['REDIRECT_STATUS'] to display different messages for different error types, since the server still doesn't think there's an error. Instead, you have to do something like this:

RewriteRule \.php$ /error.php?error=404

And then check $_GET['error'] in the script. But it's still much, much better than nothing.