PHP bug with ternary operator?
Asked Answered
D

4

0
function foo() {
    return $result = bar() ? $result : false;
}

function bar() {
    return "some_value";
}

foo();

Notice: Undefined variable: result

Is this a bug?

bar() should be saved to $result, but it doesn't. However the condition works fine and it's trying to return $result or false statement (in case bar() is NULL or false)

PHP 5.4.24

Dying answered 25/3, 2014 at 11:47 Comment(4)
Why is this a bug, its trying to read $result but it isnt defined so is telling you its undefined. Seems like by Design to me.Angadresma
It is getting value from bar() so return true => thus assigning $result which is undefined. What's wrong with that ?Stomatitis
Obvious PICNIC going on here.. :)Peale
see incorrect associativity of ternary operatorDoorsill
V
11

That's because operators precedence. Do

function foo() {
    return ($result = bar()) ? $result : false;
}

-so assignment will be evaluated with higher precedence.

Vacla answered 25/3, 2014 at 11:50 Comment(1)
Great! Yep.. without parentheses it returns $result as evaluation of subsequent condition. Thanks!Dying
D
2

more elegant solution:

function foo() {
    return bar() ?: false; 
}
Dying answered 25/3, 2014 at 21:44 Comment(0)
E
0

Can't we do just:

function foo() {
    return bar() ? $result : false;
}

function bar() {
    return "some_value";
}

foo();
Ebullient answered 25/3, 2014 at 11:55 Comment(1)
.. and you'll get undefined $result variable (because you'll try to return it)Vacla
B
0

Using the side-effect of a sub-expression within the same expression is always risky, even if the operator precedence is correct.

Even if it's necessary to evaluate the result of $result = bar() in order to test the condition, there's no general guarantee that that result will be used later in the expression, rather than a value taken before the assignment.

See for instance Operator Precedence vs Order of Evaluation which discusses this in the context of C++, and gives this classic example:

a = a++ + ++a; 

Having side-effects inside a condition is also hard to read - it might be read as $result == bar(), which would mean something entirely different.

So, in this case, the problem was just PHP's unfortunate associativity of ? :, but writing code like this is a bad idea anyway, and you can trivially make it much more readable and reliable by taking the side-effect out of the left-hand side:

$result = bar();
return $result ? $result : false;

Or in this case, assuming $result is not global or static:

return bar() ?: false;
Brigantine answered 5/2, 2019 at 10:19 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.