unusual ternary operation

后端 未结 7 722
别那么骄傲
别那么骄傲 2020-12-18 21:56

I was asked to perform this operation of ternary operator use:

$test=\'one\';

echo $test == \'one\' ? \'one\' :  $test == \'two\' ? \'two\' : \'three\';


        
相关标签:
7条回答
  • 2020-12-18 22:16

    PHP'S documentation says:

    Note: It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious:

    Example #3 Non-obvious Ternary Behaviour

    <?php
    // on first glance, the following appears to output 'true'
    echo (true?'true':false?'t':'f');
    
    // however, the actual output of the above is 't'
    // this is because ternary expressions are evaluated from left to right
    
    // the following is a more obvious version of the same code as above
    echo ((true ? 'true' : false) ? 't' : 'f');
    
    // here, you can see that the first expression is evaluated to 'true', which
    // in turn evaluates to (bool)true, thus returning the true branch of the
    // second ternary expression.
    ?>
    

    If you put parenthesis around the false statement, it prints one:

    echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : 'three');
    
    0 讨论(0)
  • 2020-12-18 22:21

    Well, the ? and : have equal precedence, so PHP will parse left to right evaluating each bit in turn:

    echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';
    

    First $test == 'one' returns true, so the first parens have value 'one'. Now the second ternary is evaluated like this:

    'one' /*returned by first ternary*/ ? 'two' : 'three'
    

    'one' is true (a non-empty string), so 'two' is the final result.

    0 讨论(0)
  • 2020-12-18 22:24

    Basically interpreter evaluates this expression from left to right, so:

    echo $test == 'one' ? 'one' :  $test == 'two' ? 'two' : 'three';

    is interpreted as

    echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';

    And the expression in paratheses evaluates to true, since both 'one' and 'two' are not null/o/other form of false. So if it would look like:

    echo $test == 'one' ? FALSE :  $test == 'two' ? 'two' : 'three';

    It would print three. To make it work okay, you should forget about combining ternary operators, and use regular ifs/switch for more complicated logic, or at least use the brackets, for the interpreter to understand your logic, and not perform checking in standard LTR way:

    echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : ($test == 'three' ? 'three' : 'four'));
    
    //etc... It's not the most understandable code... 
    
    //You better use:
    if($test == 'one')
        echo 'one';
    else { //or elseif()
    ...
    }
    
    //Or:
    switch($test) {
        case 'one':
            echo 'one';
            break;
        case 'two':
            echo 'two';
            break;
    //and so on...
    }
    
    0 讨论(0)
  • 2020-12-18 22:29

    Ternary operators are executed in order of appearance so you really have:

    echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';
    
    0 讨论(0)
  • 2020-12-18 22:34

    It works correctly when you use brackets:

    <?
     $test='one';
     echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : 'three');
    

    I don't understand it 100% but without brackets, to the interpreter, the statement must look like this:

    echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';
    

    the result of the first condition seems to be returned as the result of the whole ternary operation.

    0 讨论(0)
  • 2020-12-18 22:36

    I think that it is evaluated like this:

    echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';
    

    ($test == 'one' ? 'one' : $test == 'two') is non-zero/null, so 'two' is logical output

    if you want it to work correctly, write:

    echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : 'three');
    
    0 讨论(0)
提交回复
热议问题