The death of die()

Thu, Apr 16, 2009 11:13 PM
I am calling it.  The death of the PHP die function.  Now, I have no actual authority to do so.  My PHP CVS karma does not extend that far.  And I doubt it will actually get removed despite it being nothing more than an alias for exit now.

No, what I would like to call a death to is the usage of die such as:

$conn = mysql_connect($server, $user, $pass) or die("Could not connect to MySQL, but needed to tell the whole world");
I don't know who thought that particular usage was good, but they need to .... no, that is harsh.  I just really wish they had never done that.

So, what should you use?  Well, there are a couple of options depending on what context you are working in and whether or not the failure is actually catastrophic.

Exceptions

If you are using OOP in your PHP code, Exceptions are the logic choice for dealing with errors.  I have mixed feelings about them.  But, it has more to do with the catching of exceptions than the throwing of them.  If you are going to live in a world of exceptions, please catch them and provide useful error messages.  The PHP world is not too bad about that, but I have read too many Java error logs full of huge, verbose exception dumps in my life already.  Please don't follow that technique in PHP.

trigger_error

The function trigger_error is quite handy.  It allows you, a common PHP coder, to create errors just like the core system.  So, the error messages are familiar to anyone that is used to seeing PHP errors.  So, if your system is configured to log errors and not display them, errors from trigger_error will be treated the same as built in errors.

Also, errors thrown with trigger_error are caught by a custom error handler just like built in errors.  They can be logged, printed, whatever you want from that error handler, just like normal PHP errors.  There are even several levels of errors you can raise like notices, warnings, errors, and even deprecated.  Again, just like the built in PHP errors.

FATAL Errors

trigger_error is also the most suitable way, IMO, to end a script immediately.

$conn = mysql_connect($server, $user, $pass);
if(!$conn) {
    trigger_error("Could not connect to MySQL database.", E_USER_ERROR);
}

Now that will not be told to the whole world if you have display_errors set to Off as you should in any production environment.
29 comments
Gravatar for Johannes

Johannes Says:

die/exit with a numeric parameter is needed to terminate a shell script with an error code which can be used in shell scripts. Dropping would be a major change.

Gravatar for Artur Ejsmont

Artur Ejsmont Says:

That's actually a very true story and a nice solution. Im not sure if it would work as i expect every time but seems very clean and nice.

Another thing thats causing me a lot of pain is error instead of exceptions. OMFG its messy. Why cant PHP throw exceptions all over the code? some functions return false some throw errors and some throw exceptions. Its a real mess.

Than people keep on adding @ operator which IMHO should lead to public decapitation ;- ) Seriously, there is nothing more painful than looking for one hour for a bug just because its not in logs nor on the screen no matter what you set in ini.

I have seen a pecl extension to disable @ operator and i would use it but only if it became stable (http://pecl.php.net/package/scream)

Take care

Gravatar for Radical

Radical Says:

Best article on this subject I've seen in a long time...

Gravatar for Shahar Evron

Shahar Evron Says:

I use die(); sometimes for quick debugging when I don't have access to a debugger, usually in tandem with var_dump(). Although now that I think about it, I should start using assert() with ASSERT_BAIL instead (yes, apparently PHP has assertions (: )

Gravatar for Jeff Dickey

Jeff Dickey Says:

@Shahar - Actually, you should always have access to a debugger of sorts - PHPUnit. I've found that writing fluent code that throws exceptions on errors that require either logging or further processing works wonders when coming back to code that you haven't touched for a year - or a week. And having PHPUnit test suites that thrash the code thoroughly - whether it was originally developed using TDD or not - is really the only way I can prove to myself that I really know what the code is doing. I'm to the point now, after using PHPUnit for three years or so, that I'm VERY uncomfortable writing any code that isn't almost facetiously trivial unless I've got tests that exercise everything in it.

Gravatar for Yarrr

Yarrr Says:

@ArturEjsmont see http://php.net/errorexception (to throw Exceptions all the time)

Gravatar for Brian Moon

Brian Moon Says:

@Johannes, you didn't read the post clearly I guess. This is about the "or die()" syntax so common in early PHP3 tutorials and even some books.

Gravatar for Herman Radtke

Herman Radtke Says:

@Brian, so why didn't the title say "Death of the 'or die' syntax"? The title and first paragraph are so misleading, I can see why Johannes made the comment he did.

The issue doesn't seem to be with the or syntax or the die() function at all. I can still use exit(), trigger_error() or a custom function with the or operator even if the die() function is removed. The custom function can even throw an exception.

I guess the real issue here is generating proper errors. The use of if(!$var) { echo 'error message'; exit; } is equivalent using the "or die()" syntax. However, as Johannes pointed out, we still need to use exit/die to stop script execution and return a status code.

To summarize: only use die/exit stop script execution and return a status code. Use trigger_error() or an exception to generate an error message.

Gravatar for Dave

Dave Says:

I like the verbose exception stacks. It means usually I can fix an error just from the exception data.

Gravatar for Che

Che Says:

@Brian if the "or die()" syntax was so common in PHP3 tutorials then I don't see why it is still relevant, considering PHP3 was superseded by PHP4 in the year 2000?

I think it is a useful syntax for examples so that the focus of the example remains on the subject, not on error handling.

Gravatar for SpeedyG

SpeedyG Says:

As Johannes stated (die) exit(0); is useful and needed when using PHP for scripting. Couldn't agree more though with what you are saying. trigger_error is the way to go. Have to say die(var_dump($foo)); is something I type a lot debugging/deciphering code.

Gravatar for Johannes

Johannes Says:

Brian, for 20 line shell scripts even the "or die()" might make sense, and yes, I write quite many of these scripts (and throw them away a few minutes later ;-) )

Gravatar for Justin Swanhart

Justin Swanhart Says:

I personally find the following very useful for simple one-off scripts, etc:

mysql_connect(...) or die('got error while connecting to mysql: ' . mysql_error());

this exits the script gracefully and tells me exactly what the problem is..

similarly:
$res = mysql_query($sql, $conn) or die('Could not run $sql because: ', mysql_error($conn));

Gravatar for ferdhie

ferdhie Says:

I like to free myself from exception complexity by using simple die statement, unless we're working on some complex database library, die is a better choice ;)

Great article ;)

Gravatar for Gregory Patmore

Gregory Patmore Says:

isn't the 'or die' syntax a direct descendant from its Perl roots? I believe the reason that sytax was added to perl was because Larry Wall wanted to create a language that more closely mimicked how you speak (assuming you=an english speaker).

I love to use die when developing to kill the script and make sure everything is ok. Sure, exit will work just as well, but PHP is already riddled with alias functions so what's the difference?

Most people I've heard from have been taught using die(), and furthermore, almost none of them understand the traditional use of exit(). Exit is used in a lot of languages to end the processing and return an exit status to whatever invoked it. This being said, one would expect that an exit statement would return some value (traditionally an integer referencing a predefined status code, no?) letting you know that the script has finished with some indication as to how it went. Intuitively, a die() statement has a text based message letting you know that the processing was aborted do to some problem that occurred.

Although in PHP the constructs are the same, traditionally and semantically, exit means the program has ended either successfully or not, but a die statement should mean something went wrong, no?

my .02

Gravatar for Hodicska Gergely

Hodicska Gergely Says:

Be careful while if you use custom error handler your responsibility is to exit for E_USER_ERROR or not.

Gravatar for Junjie

Junjie Says:

Let's face it. die(); is bad coding. But then php was never intended to be that serious. I guess thats why java is used in enterprise applications.

Gravatar for Brian Moon

Brian Moon Says:

@Junjie: Ohh slam. I feel so inferior to your awesome Java powers now. Thanks for the useless comment.

Gravatar for Ian

Ian Says:

This may be an old post but to add my 2 cents,

As a beginner to intermediate developer I appreciate having something as simple as "or die('my custom error message')" to ease debugging since I can hardly decipher most error messages returned by mysql and some by php.

It is especially useful with mysql since mysql doesn't tell me which one of multiple queries is causing the problem if I have multiple queries in a single script. "error in syntax near blah blah blah" doesn't always help and it is useful to have "or die('first query');, or die('second query'); , etc. " But this is just a habit I formed to quickly narrow down to the query line causing the problem. I wouldn't want to go through some complicated error/exception handling for such a simple task.

Add A Comment

Your Name:


Your Email:


Your URL:


Your Comment: