开发者

unusual ternary operation

开发者 https://www.devze.com 2022-12-27 10:52 出处:网络
I was asked to perform this operation of ternary operator use: $test=\'one\'; echo $test == \'one\' ? \'one\' :$test == \'two\' ? \'two\' : \'three\';

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

$test='one';

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

Which prints two (checked using php).

I am still not sure about the logic for this. Please, can anybody tell me the log开发者_StackOverflowic for this.


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.


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...
}


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.


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');


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');


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

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


Nested ternary operations are gross! The above explanation shows why.

Basically this is the logic:

is $test == 'one'

  if TRUE then echo 'one'

  else is $test == 'two'

      if TRUE then echo 'two'

      else echo three
0

精彩评论

暂无评论...
验证码 换一张
取 消