Using 'or die()' to stop on errors in PHP
Often in PHP, I see:
$result = mysql_query($query) or die();
Coming from python, I know why 开发者_开发知识库this should work, because or
returns the first value if it is true in a boolean context, and the second value otherwise (see this).
But when I try the above technique in PHP in another context, for example something like:
$name = "John Doe";
echo $name or "Anonymous";
The or
doesn't return the first value ("John Doe"), it returns 1.
Why does this work in the mysql_query() result case, but not in other cases? Is it bad to use in a mysql_query() case (ignore the fact that I am not returning a useful error to the user)?
In PHP, variable assignment (the equals sign) and functions both take precedence over the or
operator. That means a function gets executed first, then the return value of the function is used in the or
comparison. In turn when you use two values/variables together with an or
operator, it compares the two values first then returns a Boolean value.
Therefore, the order of evaluation in this example is:
$result = mysql_query($query) or die();
mysql_query($query)
Returns either a result set for DQL queries such asSELECT
, or a Boolean value for DDL, DML or DCL queries such asCREATE
,DROP
,INSERT
,UPDATE
,DELETE
andALTER
.$result = mysql_query($query)
The result of this query execution is assigned to the variable$result
.$result /* = ... */ or die();
If it's either a result set ortrue
, it's considered true (aka "truthy") so theor
condition is satisfied and the statement ends here. Otherwise the script woulddie()
instead.
echo
is a language construct and therefore doesn't actually return a value, so it doesn't run like a function before the or
comparison is made.
As $name or "Anonymous"
is always true because the string "Anonymous"
is non-empty and therefore truthy, the echo
implicitly converts true
to 1
, hence that output.
The order of evaluation in this example is:
$name = "John Doe";
echo $name or "Anonymous";
$name = "John Doe";
Pretty straightforward — assigns the string John Doe to$name
.$name or "Anonymous"
PHP discovers that$name
contains the string John Doe, so what ends up being evaluated is the following:"John Doe" or "Anonymous"
Since at least one string is non-empty here, it's considered truthy and the condition is satisfied. This evaluation then returnstrue
.echo true /* $name or... */;
Convertstrue
to1
and prints the number 1.
Why should or
return anything? or
is a normal boolean operator. $a or $b
is true
if either $a
or $b
evaluates to true
and false
otherwise.
The difference between ||
and or
is, that or
has a lower operator precedance, even lower than =
. This is why
$result = mysql_query($query) or die();
is same as
($result = mysql_query($query)) or (die());
whereas
$result = mysql_query($query) || die();
is same as
$result = (mysql_query($query) || die());
In your case
echo $name or "Anonymous";
gets
(echo $name) or ("Anonymous");
What you are looking for probably is the ternary operator:
echo $name ?: 'Anonymous';
The above will work as of PHP 5.3, if you have only PHP 5.2 use:
echo $name ? $name : 'Anonymous';
The reason actually occurred to me shortly after asking the question. It's about operator precedence. The =
happens before the or
, so:
$result = mysql_query($query) or die();
is equivalent to:
($result = mysql_query($query)) or die();
not:
$result = (mysql_query($query) or die());
as it would be in Python. So this:
$a = false or true;
will set $a
to false, not true, which is bound to catch me out at some point in the future.
PHP does something often called "type juggling". In other words: PHP transforms the type of any value for the current use case. Since Strings will be transformed to "true" values, your expression returns true. But echo wants to print an string expression and transforms "true" to 1. Kinda annoying in some cases, but if you know it, you also know how to handle ;)
Check this out, by the way: http://php.net/manual/en/types.comparisons.php
the or
clause is evaluated first and returns a boolean which the echo
outputs. If you want to output text you need a if/else construct like:
echo ($name ? $name : 'Anonymous');
That is because echo is not a function, it's a language construct. It mimicks to be a function, but it really isn't :)
I would never use die() like this, it's kind of rough. You should handle your errors appropriately, don't just bail out.
If you wanted to replicate that behavior AND output to the screen/browser, you need a function that will return something other than TRUE. printf() can do that for you.
echo microtime."<br>";<
$str = "";
printf("%s",$str) or die();
echo "<br>".microtime();
If $str is empty, null, or false the die() will be called, otherwise, the script will finish executing.
精彩评论