Using 'or die()' to stop on errors in PHP - 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 as SELECT, or a Boolean value for DDL, DML or DCL queries such as CREATE, DROP, INSERT, UPDATE, DELETE and ALTER.
$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 or true, it's considered true (aka "truthy") so the or condition is satisfied and the statement ends here. Otherwise the script would die() 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 returns true.
echo true /* $name or... */;
Converts true to 1 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.

Related

Do all php types return a bool?

I'm currently building a website and I come across the case where I can do:
if (myString)
if (myArray),
and it seems to "return" true whenever there is data inside the variable. At least, that's what I think.
E.g.
$testVar = "test";
if ($testVar)
echo $testVar;
else
echo "Empty";
When i assert $testVar = "", then it echos "Empty".
I'm wondering if this is a defined feature of PHP, that any type will return true if it is not null or empty, as in other languages you need to do if($testVar = "") or so on.
Additionally, if this does indeed return true on all types if the variable is not empty, and I also want to check if the variable exists, would:
if (isset($testVar) && $testVar) be okay to use (in terms of practices)
I have searched for questions but can't find an answer to this exact question. To summarize:
Can any type return a bool, provided that it is not empty?
Thanks.
These types do not return true, but they are, instead, cast to true. PHP is a weak typed language, so it will automatically try to convert a variable to the correct type when required. In most instances, this means that a non-empty variable will return true.
This resource here will give you more information. Take a look at the "Converting to boolean" section, specifically.
http://www.php.net/manual/en/language.types.boolean.php
You can not check if a string is empty that way. Consider this:
$test = "0";
if ($test)
echo $test;
else
echo "Empty";
The code above prints "Empty", because "0" is a falsy value. See Booleans, section "Converting to boolean".
So the answer is:
All types can be converted to booleans, but the result might not be what you want.
The variables don't "return" a bool, but any variable can evaluate to either true or false.
Best practice is to be strict on your comparisons and not just do if($var)
For detailed comparison information, see: http://us3.php.net/manual/en/types.comparisons.php
conditional always return bool
if you need to check any empty values you need to use equalsto operator for check values
if($testVar == "") // check is $testVar is empty or not return bool-true/false
best to use functions like empty()
if(empty($testVar))
In this example when you are testing string variables:
$testVar = "test";
if ($testVar)
echo $testVar;
else
echo "Empty";
What you are asserting is if variable $testVar is set (not if it's empty or not). The variable themselves don't have a return type, but it's in the context they are used in a control flow operator such as an if statement.
i.e. if ($testVar) is same as if (isset($testVar)) (when $testVar is a string)
However, there are other cases like this:
$testVar = "0";
if ($testVar)
echo $testVar;
else
echo "Empty";
In this case, you will get "Empty" because $testVar is evaluated as a int 0.
However; if you had this:
$testVar = " 0"; // notice the space in front of 0
if ($testVar)
echo $testVar;
else
echo "Empty";
This will echo back the $testVar because the variable is both set and has a string value.
When you want to check for empty string, you have several options:
if (empty($testVar))
if (strlen($testVar)) or if (strlen($testVar) > 0) (both same)
etc...

Checking for a null value in conditional in PHP

I have found there to be multiple ways to check whether a function has correctly returned a value to the variable, for example:
Example I
$somevariable = '';
$somevariable = get_somevariable();
if ($somevariable)
{
// Do something because $somevariable is definitely not null or empty!
}
Example II
$somevariable = '';
$somevariable = get_somevariable();
if ($somevariable <> '')
{
// Do something because $somevariable is definitely not null or empty!
}
My question: what is the best practice for checking whether a variable is correct or not? Could it be different for different types of objects? For instance, if you are expecting $somevariable to be a number, would checking if it is an empty string help/post issues? What is you were to set $somevariable = 0; as its initial value?
I come from the strongly-typed world of C# so I am still trying to wrap my head around all of this.
William
It depends what you are looking for.
Check that the Variable is set:
if (isset($var))
{
echo "Var is set";
}
Checking for a number:
if (is_int($var))
{
echo "Var is a number";
}
Checking for a string:
if (is_string($var))
{
echo "var is a string";
}
Check if var contains a decimal place:
if (is_float($var))
{
echo "Var is float";
}
if you are wanting to check that the variable is not a certain type, Add: ! an exclamation mark. Example:
if (!isset($var)) // If variable is not set
{
echo "Var Is Not Set";
}
References:
http://www.php.net/manual/en/function.is-int.php
http://www.php.net/manual/en/function.is-string.php
http://www.php.net/manual/en/function.is-float.php
http://www.php.net/manual/en/function.isset.php
There is no definite answer since it depends on what the function is supposed to return, if properly documented.
For example, if the function fails by returning null, you can check using if (!is_null($retval)).
If the function fails by returning FALSE, use if ($retval !== FALSE).
If the function fails by not returning an integer value, if (is_int($retval)).
If the function fails by returning an empty string, you can use if (!empty($retval)).
and so on...
It depends on what your function may return. This kind of goes back to how to best structure functions. You should learn the PHP truth tables once and apply them. All the following things as considered falsey:
'' (empty string)
0
0.0
'0'
null
false
array() (empty array)
Everything else is truthy. If your function returns one of the above as "failed" return code and anything else as success, the most idiomatic check is:
if (!$value)
If the function may return both 0 and false (like strpos does, for example), you need to apply a more rigorous check:
if (strpos('foo', 'bar') !== false)
I'd always go with the shortest, most readable version that is not prone to false positives, which is typically if ($var)/if (!$var).
If you want to check whether is a number or not, you should make use of filter functions.
For example:
if (!filter_var($_GET['num'], FILTER_VALIDATE_INT)){
//not a number
}

A php if statement with one equal sign...? What does this mean?

I'm attempting to troubleshoot a problem, and need to understand what this if statement is saying:
if ($confirmation = $payment_modules->confirmation()) {
All the resources I can find only show if statements with double equal signs, not single. Is this one of the shorthand forms of a php if? What is it doing?
(If it's actually wrong syntax, changing it to a double equal sign doesn't resolve the problem. As-is, in some scenarios it does return true. In the scenario I'm troubleshooting, it doesn't return true until after I refresh the browser.)
Any help is greatly appreciated!!!
It's a form of shorthand, which is exactly equivalent to this:
$confirmation = $payment_modules->confirmation();
if ($confirmation) {
}
This will first assign the value of $payment_modules->confirmation() to $confirmation. The = operator will evaluate to the new value of $confirmation.
This has the same effect as writing:
$confirmation = $payment_modules->confirmation();
if ($confirmation) {
// this will get executed if $confirmation is not false, null, or zero
}
The code works because an assignment returns the value assigned, so if $payment_modules->confirmation() is true, $confirmation will be set to true, and then the assignment will return true. Same thing for false.
That's why you can use a command to assign to many variables, as in a = b = 0. Assigns zero to b and returns that zero. Therefore, it becomes a = 0. And a receives zero and it will return that zero, which can or can not be used.
Sometimes people like to do an assignment and then check if the assignment went through okay. Pair this up with functions that return false (or equivalent) on failure, and you can do an assignment and a check at the same time.
In order to understand this, remember that assignments are a kind of expression, and so (like all expressions) have a return value. That return value is equal to whatever got put into the variable. That is why you can do something like
a = b = c = 0;
to assign all of those variables at the same time.
= means assignment ( $a = 1 ), == is for comparison ( true == false is false ). I think in your example it should use = because it assigns it to the return value of confirmation, which should be something that evaluates to true.
Try doing a var_dump:
var_dump( $payment_modules->confirmation() );
See what boolean it evaluates to, and from there you can troubleshoot. Post more code if you want more help.
class test() {
public function confirmation() { return true; }
}
$boolean = test::confirmation();
var_dump( $boolean );
Will equate to true

Simple PHP isset test

This below does not seem to work how I would expect it, event though $_GET['friendid'] = 55 it is returning NULL
<?PHP
$_GET['friendid'] = 55;
$friendid = (!isset($_GET['friendid'])) ? $_GET['friendid'] : 'empty';
echo $friendid;
exit;
?>
As of PHP 7's release, you can use the null-coalescing operator (double "?") for this:
$var = $array["key"] ?? "default-value";
// which is synonymous to:
$var = isset($array["key"]) ? $array["key"] : "default-value";
In PHP 5.3+, if all you are checking on is a "truthy" value, you can use the "Elvis operator" (note that this does not check isset).
$var = $value ?: "default-value";
// which is synonymous to:
$var = $value ? $value : "default-value";
Remove the !. You don't want to negate the expression.
$friendid = isset($_GET['friendid']) ? $_GET['friendid'] : 'empty';
If you're lazy and risky, you can use error control operator # and short form of ternary operator.
$friendid = #$_GET['friendid']?: 'empty';
Currently you're working with the ternary operator:
$friendid = (!isset($_GET['friendid'])) ? $_GET['friendid'] : 'empty';
Break it down to an if-else statement and it looks like this:
if(!isset($_GET['friendid']))
$friendid = $_GET['friendid'];
else
$friendid = 'empty';
Look at what's really happening in the if statement:
!isset($_GET['friendid'])
Note the exclamation mark (!) in front of the isset function. It's another way to say, "the opposite of". What you're doing here is checking that there is no value already set in $_GET['friendid']. And if so, $friendid should take on that value.
But really, it would break since $_GET['friendid'] doesn't even exist. And you can't take the value of something that isn't there.
Taking it from the start, you have set a value for $_GET['friendid'], so that first if condition is now false and passes it on to the else option.
In this case, set the value of the $friendid variable to empty.
What you want is to remove the exclamation and then the value of $friendid will take on the value of $_GET['friendid'] if it has been previously set.
The best solution for this question, i.e. if you also need to 'check for the empty string', is empty().
$friendid = empty($_GET['friendid']) ? 'empty' : $_GET['friendid'];
empty() not only checks whether the variable is set, but additionally returns false if it is fed anything that could be considered 'empty', such as an empty string, empty array, the integer 0, boolean false, ...
I am using Null coalescing operator operator in if condition like this
if($myArr['user'] ?? false){
Which is equivalent to
if(isset($myArr['user']) && $myArr['user']){
From your reply to Philippe I think you need to have a look at the differences between empty and isset.
To summarise, isset() will return boolean TRUE if the variable exists. Hence, if you were to do
$fid = $_GET['friendid'] = "";
$exists = isset($fid);
$exists will be TRUE as $_GET['friendid'] exists. If this is not what you want I suggest you look into empty. Empty will return TRUE on the empty string (""), which seems to be what you are expecting. If you do use empty, please refer to the documentation I linked to, there are other cases where empty will return true where you may not expect it, these cases are explicitly documented at the above link.
if friendid is NOT set, friendid = friendid otherwise friendid = empty
Okay, I may have been having a similar issue not being familiar with the ! situation as jasondavis had.
Kind of confusing but finding out not having the ! as in... isset($avar) compared to !isset($avar) can make quite the difference.
So with the ! in place, is more stating a YES as in
since $_GET['friendid'] = 55; has been initialized...
tell me 'no' - the opposite - that it hasn't and set it to empty.
$friendid = (!isset($_GET['friendid'])) ? $_GET['friendid'] : 'empty';
where not having the ! tells me yes it has something in it, leave it be.
$friendid = (!isset($_GET['friendid'])) ? $_GET['friendid'] : 'empty';
Was far less confusing with if A$="" then.... work it. ( or if $A="" for those of PHP ).
I find this use of strings and variables all as strings to be very daunting at times. Even through the confusion, I can actually understand why... just makes things a tad difficult to grasp for me.
For me, if I need to know BOTH are true
key is set
value is truthy
and if not, use another result:
the shortest way is
$result = ($arr['b'] ?? 0) ?: $arr['a'];
(ie. if b is_set AND has a real value, use it. Otherwise use a)
So in this scenario:
$arr = ['a' => 'aaa', 'b' => 'bbb'];
$result = 'aaa'

problem with if statement used to determine function return

Im using an if statement to determine what to return in a function, but it seems to be not working the way i want it to.
function DoThis($dogs, $cats){
// do something with dogs, pet them perhaps.
$reg = $dogs[0];
$nate = $dogs[1];
if($cats = "dave"){return $reg;}
if($cats = "tom"){return $nate;}
}
$cats is a string (if that helps), and when entered it doesn't yield any return.
If i manually set a return, that works, but the above doesnt for some reason.
To test for equality, use the == (double equals) operator instead of the = (single equals) operator.
For example:
if("dave" == $cats){return $reg;}
if("tom" == $cats){return $nate;}
You're using the assignment operator instead of the comparison operator. Try the following instead.
$cats == "dave"
$cats == "tom"
When you say
if($cats = "dave") { ... }
you're really saying
Assign the value "dave" to the variable $cats
If the variable $cats is true after assignment, return true. Otherwise, return false
It's a common mistake, and something tha plagues old hands and new hands alike.
You need to use == to compare.
= is an assignment, so it has the effect of setting $cats to "dave" and then (because the expression evaluates to "dave", which is non-empty) it treats the if statement as being "if (true) ..." and executes the contained code.

Categories