Logical Operators and Precedence - php

So I just did some random test and understand the fundamentals of Precedence and the || and or operators but I'm having trouble understanding why $f changes:
$f = 0 || 1;
if ($f === 1){
echo "TRUE - $f";
}else{
echo "FALSE - $f";
}
$f = 0 or 1;
if ($f === 0){
echo "TRUE - $f";
}else{
echo "FALSE - $f";
}
Thanks for some insight.

What you are doing is the same as :
if (($f = 0) or 1){
// $f is being assigned the value 0, and the condition evaluates 0 or 1,
// 1 being equivalent to true, the condition is always true.
echo "TRUE - $f";
}else{
echo "FALSE - $f";
}
and
if ($f = (0 || 1)){ // which gives $f = true which returns true
echo "TRUE - $f";
}else{
echo "FALSE - $f";
}
if you want to check if $f is equal to a value or another you would do
if ($f === 0 or $f === 1)
Be aware that in php, by default an int 1 will be evaluated to bool true unless you do a strict comparison === or !==

It's normal to evaluate always to True. The reason is that OR means if that one of the values is True it will take this one.
Update to your new question:
The answer is that "||" has a greater precedence than "or"
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
You can learn more at the PHP manual website here which I found this example

the problem is here: "if ($f = 0 or 1){" :
"=" means you give the variable $f the value 0
You should use :
"==" : checks if the values are equal
"===" : checks if the left variable is identical to the right variable (value, type, etc.)

Related

Why does if($x = 1 && $x == 1) throw error but if ($x == 1 && $x = 2) doesn't in php?

In php the following code gives a warning of undefined variable $x:
if($x = 1 && $x == 1)
I thought it was equivalent to if( ($x = 1) && ($x == 1) ), but that's not the case. I've been told, it's because && has higher precedence than =, which causes the expression to get converted to:
if($x = (1 && ($x == 1)))
So far so good, but now consider:
$x=1; if($x == 1 && $x = 2)
This doesn't throw error. Why doesn't it get converted to:
$x=1; if( (($x == 1) && $x) = 2 )
I've been told thats due to = being right assosiative, but https://www.php.net/manual/en/language.operators.precedence.php says When operators have equal precedence their associativity decides how the operators are grouped.. Here we have =, && and == all being of different precedence.
P.S; My actual code is if($result != false && $res = $stmt->get_result()), which has been copied from some other reputable source, so seems like not using unneeded parenthesis is common in php.
I've played with several conditions and below is what I've got.
First, let's consider that we init $x before if statements to avoid undefined variable notice.
Second, let's confirm the precedence for operators:
== is applied 1st
&& is applied 2nd
= is applied 3rd
This returns true:
$x = 1;
if ($x = 1 && $x == 1) {
echo 'true';
} else {
echo 'false';
}
It goes like ($x = (1 && ($x == 1))) -> ($x = (1 && true)) -> ($x = true) -> true.
If we compare $x to another value than the assigned one we will get false:
$x = 1;
if ($x = 2 && $x == 2) {
echo 'true';
} else {
echo 'false';
}
It goes like ($x = (2 && ($x == 2))) -> ($x = (2 && false)) -> ($x = false) -> false.
The last one returns true:
$x = 1;
if ($x == 1 && $x = 2) {
echo 'true';
} else {
echo 'false';
}
It goes like ((($x == 1) && $x) = 2) -> ((true && $x) = 2) -> (true = 2) -> true.
The last comparison can't be interpreted by PHP so it's an approximate view.
It looks like the last action (true = 2) totally depends on the left operand. If we put $x = 2; we will get (false = 2) -> false.
I'm not sure about the last one and here is the only place were some mistakes can happen.
Otherwise, it looks like precedence works as expected.
Anyway, I always put parenthesis for an assignment action inside if operator (especially inside ternary if) to be sure that I will get what I expect.
I don't think this affects performance or readability too much, but it may prevent some logical errors.
UPDATE:
Concering your code if($result != false && $res = $stmt->get_result()) it's not correct to compare it to if($x == 1 && $x = 2) because in your code are two different variables.
In this case logical operator will not call the second part at all if the fisrt one is false, see the 1st example here
UPDATE-2:
After the discussion under this answer we can see that the last conditions ($x == 1 && $x = 2) work like like (($x == 1) && ($x = 2)) -> ((1 == 1) && 2) -> true and $x becomes 2 after it.

Using 'and' and 'or' in an if/else PHP statement

I am attempting to use both AND and OR statements in my IF/ELSE statement, but I cannot get the desired effect.
What I would like to achieve is that if either 'a' or 'b' has a value of '1' but both 'c' and 'd' must be 1 then I get 'Yes'.
All my attempts have given me either 'Yes' or have not worked (blank screen).
<?php
$a = "0";
$b = "1";
$c = "1";
$d = "1";
if (($a == "1") || ($b == "1") && ($c == "1") && ($d == "1")) {
echo "Yes";
}
else {
echo "No";
}
?>
Thank you.
You need and extra parenthesis, to make sure the evaluation order will be done correctly, like in math:
if ( ( ($a == "1") || ($b == "1") ) && ($c == "1") && ($d == "1")) {
^ ^
That way, let's say for example:
$a = 1;
$b = 2;
$c = 1;
$d = 2;
The first parenthesis will be evaluated as true || false. The final result will be true.
So now you have true && ($c == "1") && ($d == "1")
$c = 1, so again, the next evaluation will be true && true && ($d == 1)
$d = 2, so the next round will be true && true && false, final result, in this example, will be false.
You need to add parenthesis.
Why?
Because inner parenthesis are evaluated first before outer parenthesis. Take this example:
((1 == 1 && (2 == 2)) || 3 == 3)
What will be evaluated first? The 2 == 2 then the 1 == 1 and then the 3 == 3. In your if condition, because you are mixing AND's and OR's, you will not get the desired affect.
( (($a == "1") || ($b == "1")) && ($c == "1") && ($d == "1") )
Should work for you. In fact you can do this so that it looks even better:
(($a == 1 || $b == 1) && $c == 1 && $d == 1)
Because it is not necessary to put 1 in quotes ie: "1". PHP's truthiness will evaluate 1 == "1" to be true. However if you wanted to check for an actual string that contains 1, then you would use the === operator.
$a = 1;
$b = "1"
$a == "1"; // true
$b == 1; // true
$a === "1"; // false
$b === "1"; // true
However for more information go here: http://php.net/manual/en/language.operators.precedence.php
The equality operators will be evaluated first, then &&, then ||. Parentheses will be evaluated before anything else, so adding them can change the order.
Check the answer In Java, what are the boolean "order of operations"?
It will always echo a Yes because PHP interpreter places The AND operation before the OR operation.
So your if statement interpretes like this:
If
a = 1 or b = 1 and c = 1 and d = 1
then
echo 'Yes'
else
echo 'No'
That's why you always get a yes..

! ( NULL || 0 || '' ) if condition in PHP at the same time

If I want to check the variable I need to do this:
if ( $i != '' || $i != 0 || $i != NULL ) {
// ...do some code
}
Could these 3 checks be somehow merged into 1 via some php function or a trick?
if (!empty($i)) {
// ... do some code
}
Please see http://php.net/manual/function.empty.php
All of them are actualy falsey. So you could do
if(!$i) {
}
http://php.net/manual/en/language.types.boolean.php
I should probably elaborate on why the OP has some bad assumptions. The list of things PHP will evaluate to false is long
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
This is where equivalency comes into play. It's a comparison operator. The OP has this
if ( $i != '' || $i != 0 || $i != NULL )
All three are actually the same test. Take this code
$i = 0;
if($i == '') {
echo 'true';
}
if($i == 0) {
echo 'true';
}
if($i == NULL) {
echo 'true';
}
All three statements will echo out. So if you want to know if $i is actually NULL or false as opposed to 0 (and some functions will return both) you have to use a different operator. === is used to see if the two are equivalent and not simply equal.
$i = 0;
if($i == NULL) {
echo 'true'; //This will succeed
}
if($i === NULL) {
echo 'true'; //This will NOT succeed
}

AND operator behavior with/without brackets

$a = true and false; //true
$b = true && false; //false
$c = (true and false); //false
$d = (true && false); //false
Why gives case 'a' true?
I thought that and and && has the same precedence but they don't.
As stated in the documentation, this is expected bahvior
// The constant true is assigned to $h and then false is ignored
// Acts like: (($h = true) and false)
$h = true and false;
http://php.net/manual/en/language.operators.logical.php
The constant true is assigned to $a and then false is ignored. It's all about operator precedences

Weird PHP number issue

Here is the simple code:
$result = 0;
$result = $obj->delete($this_id);
echo "Result:" . $result;
var_dump($result);
if ( (int) $result < 0 || $result == null ) {
echo "Here" . $result;
var_dump($result);exit;
}
Here is the result:
Result:0int(0)
Here0int(0)
Its not supposed to enter into if block. Because $result is = 0. Not < 0.
Am I missing something or PHP handles this differently?
The comparison to null should be === instead of ==. Since null can evalulate to 0, the comparision evaluates (0 == null) = true
if ( (int) $result < 0 || $result === null ) {
See http://php.net/manual/en/language.operators.comparison.php for more information
It looks like the cast to an int type is making your variable test incorrectly against 0.
Replace if( (int) $result ... with if( $result ...
Its not the first validation which matches:
var_dump(0 == null); //true
var_dump(false == null); //true

Categories