views:

44

answers:

3

Hi all,

I'm trying to find a clean way to handle fatal and critical errors (i.e. without output buffering), and I read that using HTTP headers in register_shutdown_function is impossible.

The thing is, I'd like to redirect to a generic static error page when a critical error occurred (e.g.: service unavailable).

How should I do ?

Display a or using Javascript do not seem satisfactory solutions.

Thanks for your help !

A: 

You could simply replace apache default error page, using the ErrorDocument directive : http://httpd.apache.org/docs/2.0/mod/core.html#errordocument

greg0ire
well, a PHP fatal (or critical) error will not, in most cases, trigger an Apache error...I considered this solution for a while, though... but forcing an apache error is kinda dirty, no ?
Rolf
I see what you mean... here is another solution, found on a blog : http://www.thedeveloperday.com/php-fatal-error-handling/
greg0ire
A: 

and I read that using HTTP headers in register_shutdown_function

Where did you read that? It's wrong. Anything which happens in register_shutdown_function should not write back to the browser. In most cases the output stream will no longer be available.

I'm trying to find a clean to handle fatal errors

Then you can't do it with PHP code - fatal means your PHP has died - it can't do anything after the error.

Fatal errors are caused by

  • bugs in your code
  • bugs in PHP
  • bugs in the webserver

The latter 2 are very uncommon - the first is your responsibility to identify and fix. While as greOire suggests, you should have your own, branded errorDocument page(s) (but do read the note about MSIE) this is not going to help when the error occurs after your PHP code has started executing. And at that point the webserver assumes tat the response code will be 200 OK unless PHP tells it something different.

There should never be fatal errors in your code at runtime which cannot be replicated at development time - as long as your testing has full code coverage. But I admit that's not always practical - you need to ensure that your error logging is set up correctly and that you check your logs for fatal errors in PHP.

C.

symcbean
ok, sorry, I re-read a bit too fast, the text is now corrected and I hope is clearer...I think you missed my point: I'm talking about finding a user-friendly way to uniformly display error pages (rather than a cheap white page), and this also implies to handle fatal errors...the cleanest way, imho, to handle these is to rely on register_shutdown_function, but any http redirection within is impossible, so I'm looking for an alternative...
Rolf
A: 

symcbean's answer is correct by the book, but not always in practice. Even though you shouldn't create output in a shutdown handler, you can do so under select circumstances.

Check out headers_sent(). In your shutdown function, check it. If headers have not been sent yet, then you can echo new headers and actual content if needed. You can use error_get_last() to determine if the shutdown is due to an error or not. The following error types are uncatchable and will kill the script and call shutdown functions:

  • E_ERROR
  • E_PARSE
  • E_CORE_ERROR
  • E_COMPILE_ERROR

If the error type is one of those, and headers haven't been sent, then your shutdown handler can create output, including headers.

You must not create output from a shutdown handler if headers have been sent. Those headers could include Content-length, and sending more content than you said you would is bad. Even then, if headers have been sent, any output you create may have nowhere to go, depending on the version of PHP being used, the underlying web server software, and whether or not it's FastCGI.

In fact, this answer may be totally bogus outside of mod_php and FastCGI on Apache 2.2.x. YMMV, but good luck.

Charles