The behaviour of the or operator in PHP

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 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 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 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

    链接地址: http://www.djcxy.com/p/10098.html

    上一篇: PHP逻辑运算符优先级奇怪地影响变量赋值结果

    下一篇: PHP中的or运算符的行为