I'm trying to understand the behavior of or
operator. Please see the below examples:
$e = false || true;
var_dump($e);
Output is as expected: bool(true);
$f = false or true;
var_dump($f);
Output is as expected: bool(false)
. I understood this in a way that the =
has a higher precedence than the Or
, so that's why the $f
is assigned to false
.
But the below code works quite opposite of what I thought. I thought that the $foo
will be assigned to 5
and then compared to itself.
But the $foo
is getting assigned only when if the $foo
is set that means it is checking if the $foo
is assigned to anything before, assign 5 to it.
$foo or $foo = 5;
Can anyone explain why this is so?
The basics:
An assignment expression results in the assigned value.
What does that mean? $foo = 'bar'
is an expression, in which the assignment operator =
assigns a value. An expression always returns a value itself. Just like the expression 1 + 2
results in the value 3
, the expression $foo = 'bar'
results in the value 'bar'
. That's why this works:
$foo = $bar = 'baz'; // which is: $foo = ($bar = 'baz');
Boolean operations are short-circuiting operations. Both sides are not always evaluated if they don't need to be. true || false
is always true
overall, since the lefthand operand is true
, so the whole expression must be true
. false
is not even being evaluated here.
Operator precedence dictates in which order parts of an expression are grouped into sub-expressions. Higher precedence operators are grouped with their operands before lower precedence operators.
Therefore:
$e = false || true;
false || true
is being evaluated, which results in the value true
, which is assigned to $e
. The ||
operator has a higher precedence than =
, therefore false || true
is grouped into an expression (as opposed to ($e = false) || true
).
$f = false or true;
Here now or
has a lower precedence than =
, which means the assignment operation is grouped into one expression before or
. So first the $f = false
expression is evaluated, the result of which is false
(see above). So then you have the simple expression false or true
which is evaluated next and results in true
, but which nobody cares about.
The evaluation works like this:
1. $f = false or true;
2. ($f = false) or true; // precedence grouping
3. false or true; // evaluation of left side ($f is now false)
4. true; // result
Now:
$foo or $foo = 5;
Here, again, $foo = 5
has a higher precedence and is treated as one expression. Since it occurs on the right side of the or
operator, the expression is only evaluated if necessary. It depends on what $foo
is initially. If $foo
is true
, the right hand side will not be evaluated at all, since true or ($foo = 5)
must be true
overall. If $foo
has a falsey value initially though, the right hand side is evaluated and 5
is assigned to $foo
, which results in 5
, which is true-ish, which means the overall expression is true
, which nobody cares about.
1. $foo or $foo = 5;
2. $foo or ($foo = 5); // precedence grouping
3. false or ($foo = 5); // evaluation of left side
4. false or 5; // evaluation of right side ($foo is now 5)
5. true; // result
As per the php.net webpage about Logical Operators:
This:
$e = false || true;
Acts like this:
$e = (false || true) // If false is true, then $e = false. Otherwise true
This:
$f = false or true;
Would act like this:
($f = false) or true; // $f = false is true, as the assignment succeeded
This:
$foo or $foo = 5;
Would act like this:
$foo or ($foo = 5) // foo = undefined or foo = 5, so foo = 5
For the last one, undefined is basically like false, therefore foo equals 5.
Also, here's the link for the operator precedence order: http://www.php.net/manual/en/language.operators.precedence.php
UPDATE:
Ok, now let's get to the main point. Like how we all know when using a fetched query:
while($row = @mysql_fetch_assoc($result))
And we all know while loops only execute on true
, therefore $row = @mysql_fetch_assoc($result)
returns true.
Same with Daric's question.
$foo or $foo = 5;
Is basically:
$foo or ($foo = 5);
Which is basically:
$foo = undefined or ($foo = 5); // $foo = 5 actually returns true
Which is also
$foo = undefined or true;
And as I have previously mentioned, undefined = false, so therefore $foo = 5 (as that is the true statement).
I hope everyone can understand.
$foo or $foo = 5;
Suppose let say $foo=true or $foo=5;
here it will not evaluate after or operator expresion so output will be $foo=1
Now the expression is
$foo=false or $foo=5;
Here it will evaluate after or as = higher precedence so $foo
as of which of which it will evaluate $foo=5
so output will be 5
But when we evaluate $foo=false or true
so here it will consider = higher precedence so the output will be $foo=false
but whole expression will evaluate as true because false or true
becomes false
<?php
$foo = false;
$foo or ($foo = '5');
echo $foo;
?>
Check this you can assign the value "5" for $foo
.
Compare than or
=
has high priority.. Thats the fact.... :)