php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30825 Ternary operator (?:) goes wrong
Submitted: 2004-11-18 15:40 UTC Modified: 2004-11-18 16:44 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: Arne dot Heizmann at csr dot com Assigned:
Status: Not a bug Package: Unknown/Other Function
PHP Version: 4.3.9 OS: Windows XP
Private report: No CVE-ID: None
 [2004-11-18 15:40 UTC] Arne dot Heizmann at csr dot com
Description:
------------
The ternary conditional operator (?:) goes wrong when nested two levels deep.

When adding parentheses, the bug disappears, even when the parentheses are redundant and shouldn't make any difference.

Reproduce code:
---------------
echo    true    ?   "Yes"   :
        false   ?   "No"    :   "No2";

Expected result:
----------------
"Yes"

Actual result:
--------------
"No"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-11-18 16:03 UTC] tony2001@php.net
Could tell me how do you think it should work:
like this
echo (true ? "Yes" : false) ? "No" : "No2";
or like this 
echo true ? "Yes" : (false ? "No" : "No2");
and why ?
 [2004-11-18 16:05 UTC] Arne dot Heizmann at csr dot com
I understand now that the test case outputs "No" because it interprets the code as:

echo   (true    ?   "Yes"   :
        false)  ?   "No"    :   "No2";

but clearly this is not useful; I think the precedence of the operator should be changed so that programmers won't have to insert extra parentheses to disambiguate the construct.
 [2004-11-18 16:08 UTC] Arne dot Heizmann at csr dot com
Ah... thanks for your comment, tony2001@php.net.

I think it should work the other way than it does because it is more useful. Situations in which you want to use the result of a conditional ?: operation as the condition in other ?: operation are extremely rare. It is much more likely that you want to go through a set of cases, such as:

$result = $var == 1 ? 'Result 1' :
          $var == 2 ? 'Result 2' :
          $var == 3 ? 'Result 3' :
          $var == 4 ? 'Result 4' :
          '';

According to the way the operator currently works, this requires a heck of a lot of parentheses:

$result =  $var == 1 ? 'Result 1' :
          ($var == 2 ? 'Result 2' :
          ($var == 3 ? 'Result 3' :
          ($var == 4 ? 'Result 4' :
           '')));

which I think is pretty ugly.
 [2004-11-18 16:15 UTC] Arne dot Heizmann at csr dot com
Sorry for the comment spam, but here's another reason why the way it currently works is less useful. Suppose you actually *did* want this:

echo  (a() ? b() : c()) ? d() : e();

Since humans don't tend to think this way, you would be more likely to write this as:

echo  (a() && b()) || (!a() && c()) ? d() : e();

and this would be more readable and understandable anyway.
 [2004-11-18 16:44 UTC] derick@php.net
There is no way we can change this as other people rely on this. This is also expected behavior.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Wed Oct 07 21:00:02 2026 UTC