Dying with grace – PHP’s register_shutdown_function

Please see my new blog


Update:

I guess I didn’t make the purpose quite clear here. This method will allow you to show custom error messages when PHP hits a fatal error. The shutdown function will always run.

Scripts tend to die, and that’s not usually nice. We do not want to show the user a fatal error nor a blank page (display errors off) . PHP has a function called register_shutdown_function which lets us set up a function which is called at execution shutdown. What this means is that our function will be executed when our script is done executing / dying and PHP execution is about to shut down. By setting up a variable to false at the start of our script, and setting it to true at the very end of the script we can have our shutdown function check if the script completed successfully or not. If our variable is still false we know that we never made it to the last line of our script, hence it died somewhere. I’ve prepared a very basic sample which shows how you can give the user some proper feedback if a fatal error should arise. You’d want to turn of display of fatal errors for this to look nice.

<?php
$clean = false;
function shutdown_func(){
global $clean;
if (!$clean){
die(“not a clean shutdown”);
}
}

register_shutdown_function(‘shutdown_func’);

$a = 1;
$a = new FooClass(); // will fail with fatal

$clean = true;
?>

As you can see, the shutdown_func prints something if the clean variable isn’t set to true when the shutdown function runs. This should of course be wrapped in a class (and NOT use globals), and for something more usable I recommend checking EZ Components way of doing this.

About these ads

9 Comments

  1. Josh said,

    March 16, 2008 at 1:45 pm

    This is definitely useful in a CLI context, where a user may decide to prematurely terminate a long-running CLI script, and it can clean up after itself – maybe even print some last-minute report info. The Windows ping utility works similarly.

    However, in my opinion, shutdown functions have no place in a web-based context. Errors should be handled properly – caught, or better still, avoided in the first place. On the occasion that a system issue, such as a power outage (and brief UPS lifeline), causes your script to execute, you could have hundreds of PHP/Apache threads running around trying to clean up after themselves when the system should be halting.

    I guess it comes down to one key issue – you attempt to die in grace when you should have no need to die at all, or should not waste CPU cycles with grace on the odd occasion you do.

  2. March 17, 2008 at 5:41 am

    [...] didn’t agree with Dying with grace – PHP’s register_shutdown_function but it lead me to read this Re: Shutdown error handlers which makes me wonder why I click on [...]

  3. eirikhoem said,

    March 17, 2008 at 2:20 pm

    @Josh

    Thanks for the feedback. I fully agree that it can be very usable in a CLI context, and I do use it in several scripts which needs summaries etc.

    Did you see the discussion over at Richard Heyes (“phpguru”) blog?

    He made a follow up on my post where he states his disagreements regarding the usage I present. I agree that avoiding / catching errors is a must, but this code we have here actually lets the developer present information when a fatal error comes along. I don’t think I made that clear enough in my initial post, so I’ve updated it.

    I did not consider your point regarding the PHP/Apache thread cleaning up when writing this post, but I do find it pretty interesting.

  4. Sam Minnée said,

    March 17, 2008 at 7:38 pm

    It seems to me that it would be better to use set_error_handler() for this kind of operation.

    Here’s a real-world example from SilverStripe CMS: http://open.silverstripe.com/browser/modules/sapphire/trunk/core/Debug.php

  5. Doug Hill said,

    March 17, 2008 at 7:44 pm

    Eirik,

    After thinking about it a bit more, I think it has some merit for debugging purposes although I pretty much agree with the other comment, you should never hit that point in a web application.

    Doug

  6. March 18, 2008 at 6:57 am

    [...] Hoem on his blog provides an overview of PHP’s register_shutdown_function, and suggests using it for the cases when for whatever [...]

  7. eirikhoem said,

    March 18, 2008 at 9:09 am

    @Sam: Thanks for the comment. That would in fact not work, since set_error_handler functions cannot handle fatal errors (which the method I present is mostly about).

  8. Daniel said,

    March 19, 2008 at 11:33 am

    This functionality can be used in web application, IMHO, if you have large legacy codebase which runs as complex CMS / CRM.

    For example if you work with very large (and very old) system usually there is no enough time (and money) to write all legacy stuff from the beginning or even do necessary refactoring. New code very often uses legacy functionality.

    Of course QA are not able to test everything and unit tests do not exist for legacy functionality. As a result, from time to time fatal errors can occur in production environment (user sees white screen or not completed layout).

    register_shutdown_function could help with display user friendly message to make sure customer will not be wondering what just has happened.

  9. March 20, 2008 at 3:05 am

    [...] This is a useful function to catch such exceptions in your script. Eirik Hoem’s written an article on this function over at his blog, where he shows an example on how to trap a premature end of [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: