This is an old revision of the document!
PHP RFC: Deprecate left-associative ternary operator
- Date: 2019-04-09
- Author: Nikita Popov nikic@php.net
- Status: Under Discussion
- Target Version: PHP 7.4 and PHP 8.0
- Implementation: https://github.com/php/php-src/pull/4017
Introduction
Unlike most (all?) other languages, the ternary operator in PHP is left-associative rather than right-associative. The left-associative behavior is generally not useful and confusing for programmers who switch between different languages. This RFC proposes to deprecate and remove left-associativity for the ternary operator and require explicit use of parentheses instead.
As an example, the code
return $a == 1 ? 'one' : $a == 2 ? 'two' : $a == 3 ? 'three' : $a == 4 ? 'four' : 'other';
would in most (all?) other languages be interpreted as
return $a == 1 ? 'one' : ($a == 2 ? 'two' : ($a == 3 ? 'three' : ($a == 4 ? 'four' : 'other')));
which is both the useful and intuitive interpretation. In PHP, it is instead interpreted as
return ((($a == 1 ? 'one' : $a == 2) ? 'two' : $a == 3) ? 'three' : $a == 4) ? 'four' : 'other';
which is generally not what was intended.
Proposal
In PHP 7.4 using nested ternaries without explicit parentheses will throw a deprecation warning. In PHP 8.0 it will become a compile-time error instead.
1 ? 2 : 3 ? 4 : 5; // deprecated (1 ? 2 : 3) ? 4 : 5; // ok 1 ? 2 : (3 ? 4 : 5); // ok
This also applies when mixing short and long ternary syntax:
1 ?: 2 ? 3 : 4; // deprecated (1 ?: 2) ? 3 : 4; // ok 1 ?: (2 ? 3 : 4); // ok 1 ? 2 : 3 ?: 4; // deprecated (1 ? 2 : 3) ?: 4; // ok 1 ? 2 : (3 ?: 4); // ok
However, as an exception, explicit parenthesis are not required when combining two short ternaries:
1 ?: 2 ?: 3; // ok (1 ?: 2) ?: 3; // ok 1 ?: (2 ?: 3); // ok
The reason is that ($a ?: $b) ?: $c
and $a ?: ($b ?: $c)
will always yield
the same result, even though the left-associative version will arrive at it in a less efficient
manner.
Parentheses are also not required when nesting into the middle operand, as this is always unambiguous and not affected by associativity:
1 ? 2 ? 3 : 4 : 5 // ok 1 ? 2 ?: 3 : 4 // ok
The null-coalesce operator ??
is already right-associative and not affected by these changes.
Backward Incompatible Changes
Code exploiting left-associativity of the ternary operator will become a hard error in PHP 8. As left-associative ternaries are almost certainly bugs, the impact of this change should be minimal.
Future Scope
We could make the ternary right-associative, either directly in PHP 8 or at a later point in time, after it has been an error for a while. Because the current left-associative interpretation is so unlikely to be used intentionally, this is a viable change.
Vote
Straightforward Yes/No vote.