As part of my migration from /blog/ to /, I had to set up some re-directs in my .htaccess file. I started off with some RegEx RewriteRule hackery that stripped off the .html extension for certain files, but quickly decided that solution was undesirable because I would have to update it as more of my files were transitioned to extension-free PHP scripts. I rarely remember to do anything; modifying regular expressions is something that I’d prefer to forget.
So I switched to simple Redirect statements and wrote a basic 404 handler in PHP which checks that an extension-free version of a file exists before re-directing. Otherwise it displays a helpful 404 page. I’ll never need to update the script, so it’s perfect for me.
With 404s fully handled, I moved on to handling scripting errors and was quickly reminded that PHP is a steaming pile of doggie doo. Dropping a ; generates a fatal parsing error. Loading an XML or XSLT file with an improperly closed tag generates 17 domxml warnings, followed by one fatal error when the script tries to access the object that domxml didn’t return. To my way of thinking, the right thing to do is ignore the warnings, catch the fatal errors, and return a basic 500 Internal Server Error page. PHP’s error-handling routines, however, do not allow any sort of fatal error to be caught.
For now I’ve added code to test that xmldom returned an object, and display a pretty 500 page when it does not. Any other scripting error will continue to display a blank page, which I feels is slightly less lame than PHP’s display_errors output.
I did find an alternative solution for catching fatal PHP errors. It uses display_errors, output_buffering, and a user-defined output_handler to do a sub-string search for error messages on the output buffer. It’s an icky hack, and my PHP installation doesn’t seem to like output_handler anyway, but… I realized that the same effect can be achieved without display_errors and a sub-string search by using output_buffering, ob_start('output_handler_func'), and an output_handler_func that simply checks for an empty output buffer. Still a hack but not so icky, I’ll finish implementing that method later if nothing better presents itself.
Or maybe I should just switch to a scripting environment that offers proper exception handling.
