Ternary operator in PHP gives unexpected result

3

I recently ran a test and there was a question asking what the return of the expression:

$var = true ? '1' : false ? '2' : '3'

I replied that the result would be '1', but the correct result is '2'. If the code is written:

$var = true ? '1' : (false ? '2' : '3')

It will return '1'.

Why?

    
asked by anonymous 12.11.2018 / 00:06

1 answer

7

This is a problem of associativity, and "per table", of precedence . Every well-thought-out and well-made language has this operator with right-to-left associativity. This makes a lot more sense in this type of operator, but PHP obviously chose the wrong way, like so many other things, and uses associativity from left to right. Join the fact that it is a weak typing language and interpret one type as if it were another, it is the confusion. So let's put brackets in the code to make it easier to understand what it does, remembering that the operator is completely plus the left is a single operation:

(true ? '1' : false) ? '2' : '3'

The result of the expression in parentheses (obviously the first one to be executed? If it is true, of course the result is '1' . p>

'1' ? '2' : '3'

'1' is true or false? According to documentation it is considered true by PHP, any value that is false , 0, 0.0, "0", array or SimpleXML (do not ask me why it only has this exception) of zero elements, or NULL, is false, the rest is true.

So being true, the result is '2' .

The second you are changing precedence with explicit parenthesis, presumably, where you want. The first expression is isolated and because the condition is already true already falls on the first operand after the condition, the false operand is never executed in this case, it neither evaluates the expression that is in parentheses.

However, in any programming language, you should avoid nesting conditional operators (do not call them ternary ones because one day you can have another ternary that is not that conditional, ternary is another classification level of what it is). If you are going to nest, prefer to be more readable by placing explicit parenthesis on what you want. This applies to any operator that does not have such obvious precedence (ie, all non-arithmetic, and probably relational are also very quiet, for those who are experienced can risk the logic.)

echo true ? '1' : false ? '2' : '3';
echo "\n";
echo true ? '1' : (false ? '2' : '3');

See running on ideone . And no Coding Ground . Also I placed GitHub for future reference .

    
12.11.2018 / 00:38