Why do I need to add a parenthesis under multiple conditions of a ternary operator?

Asked

Viewed 61 times

3

Let’s start from the following values:

$foo = 1;
$bar = 1;

As the extra condition placed on else without parentheses, the result does not match the intention of the operator:

echo ($foo && $bar) ? 'Foo Bar' : ($foo) ? 'Foo' : ''; //Foo

But when parentheses are added, the result is displayed according to the operator’s intention:

echo ($foo && $bar) ? 'Foo Bar' : (($foo) ? 'Foo' : ''); //Foo Bar

1 answer

7


Question of precedence and association of operators, the language finds a situation that an operand may belong to an operator or another, it has to make a decision to which operator that operand will be used, and it documented how she decides.

Parentheses are to change precedence, after all they take precedence over almost everything in language. This is not there in the precedence documentation (PHP is like this, all done in half), someone must think that is not an operator.

We can understand precedence, roughly speaking, as a form of the compiler by parentheses in specific places, so by the rule adopted what you wrote is actually this:

echo (($foo && $bar) ? 'Foo Bar' : $foo) ? 'Foo' : '';

When you have two operators with the same precedence, and of course the same operator has the same precedence, then you have to look at the association, and in the case of the conditional operator (I do not like the term ternary because this is circumstantial and there could be other ternaries who do something else) the association is left to right, so he tries to complete his execution with the three operands he finds as directly as possible, so he finds a simple operand after the : he considers that the operator is complete and closes his analysis right there.

Then the entire result of the first conditional operator will be the first operand of the next conditional operator used, which will probably (in this case certainly) give problem because the first operand of this operator has to always result in a boolean (not the case in this code, it results in string or number, although in a weak typing language this can be considered as a boolean, but certainly what you expect, except by coincidence, and then find the bug it’s not easy at all).

With the parentheses you adjust this and it now considers that the result of all the conditional operator placed next is that it should be used as the third operand of the first operator and therefore what should result if the first operator gives false.

echo ($foo && $bar) ? 'Foo Bar' : ($foo ? 'Foo' : '');

I put in the Github for future reference.

I took a couple of unnecessary parentheses. I left the others because they help readability, but could withdraw without changing the result because the precedence of the && is greater than the ? :

When you need to nest conditional operators it is recommended to make it even clearer by separating each part in a row or prefer at least one of them as if.

  • Thanks for the excellent explanation @Maniero.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.