In PHP, you can handle errors by calling or die
to exit when you encounter certain errors, like this:
$handle = fopen($location, "r") or die("Couldn't get handle");
Using die()
isn't a great way to handle errors. I'd rather return an error code so the parent function can decide what to do, instead of just ending the script ungracefully and displaying the error to the user.
However, PHP shows an error when I try to replace or die
with or return
, like this:
$handle = fopen($location, "r") or return 0;
Why does or die()
work, but not or return 0
?
I want to thank you for asking this question, since I had no idea that you couldn't perform an
or return
in PHP. I was as surprised as you when I tested it. This question gave me a good excuse to do some research and play around in PHP's internals, which was actually quite fun. However, I'm not an expert on PHP's internals, so the following is a layman's view of the PHP internals, although I think it's fairly accurate.or return
doesn't work becausereturn
isn't considered an "expression" by the language parser - simple as that.The keyword
or
is defined in the PHP language as a token calledT_LOGICAL_OR
, and the only expression where it seems to be defined looks like this:Don't worry about the bits in the braces - that just defines how the actual "or" logic is handled. What you're left with is
expr T_LOGICAL_OR expr
, which just says that it's a valid expression to have an expression, followed by theT_LOGICAL_OR
token, followed by another expression.An
expr
is also defined by the parser, as you would expect. It can either be ar_variable
, which just means that it's a variable that you're allowed to read, or anexpr_without_variable
, which is a fancy way of saying that an expression can be made of other expressions.You can do
or die()
because the language constructdie
(not a function!) and its aliasexit
are both represented by the tokenT_EXIT
, andT_EXIT
is considered a validexpr_without_variable
, whereas thereturn
statement - tokenT_RETURN
- is not.Now, why is
T_EXIT
considered an expression butT_RETURN
is not? Honestly, I have no clue. Maybe it was just a design choice made just to allow theor die()
construct that you're asking about. The fact that it used to be so widely used - at least in things like tutorials, since I can't speak to a large volume of production code - seems to imply that this may have been an intentional choice. You would have to ask the language developers to know for sure.With all of that said, this shouldn't matter. While the
or die()
construct seemed ubiquitous in tutorials (see above) a few years ago, it's not really recommended, since it's an example of "clever code".or die()
isn't a construct of its own, but rather it's a trick which uses - some might say abuses - two side-effects of theor
operator:or
) is not executed if the first operand returnsTRUE
, since if one operand isTRUE
in anor
expression, then they both are.Some people consider this sort of trickery to be unfavourable, since it is harder for a programmer to read yet only saves a few characters of space in the source code. Since programmer time is expensive, and disk space is cheap, you can see why people don't like this.
Instead, you should be explicit with your intent by expanding your code into a full-fledged
if
statement:You can even do the variable assignment right in the
if
statement. Some people still find this unreadable, but most people (myself included) disagree:One last thing: it is convention that returning
0
as a status code indicates success, so you would probably want to return a different value to indicate that you couldn't open the file.Return is fairly special - it cannot be anything like a function since it's a tool to exit functions. Imagine this:
If it was like this, return would have to be a function that does a "double exit", leaving not just its own scope but the caller's, too. Therefore return is nothing like an expression, it simply can't work that way.
Now in theory, return could be an expression that evaluates to (say) false and then quits the function; maybe a later php version will implement this.
The same thing applies to goto which would be a charm to work as a fallback; and yes, fallbacks are necessary and often make the code readable, so if someone complains about "clever code" (which certainly is a good point) maybe php should have some "official" way to do such a thing:
Something like try...catch, just more to the point. And personally, I'd be a lot happier with "or" doing this job since it's working well with English grammar: "connect or report failure".
TLDR: you're absolutely right: return, goto, break - none of them works. Easy to understand why but still annoying.
I've also stumbled upon that once. All I could find was this:
https://bugs.php.net/bug.php?id=40712
Look at the comment down below:
I've searched in the documentation and I think it's due to the fact that
return 0
is a statement whereasdie()
is essentially an expression. You can't run$handle = return 0;
but$handle = fun();
is valid code.Regarding error handling I would recommend custom codes or using custom handlers and triggers. The latter are described here for example.