необычная тройная операция

Меня попросили выполнить эту операцию использования троичного оператора:

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

Что печатает два (проверено с использованием php).

Я до сих пор не уверен в логике этого. Пожалуйста, может кто-нибудь сказать мне логику для этого.

Solutions Collecting From Web of "необычная тройная операция"

Ну, а? и: имеют одинаковый приоритет, поэтому PHP будет анализировать слева направо, оценивая каждый бит по очереди:

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

Первый $test == 'one' возвращает true, поэтому первые parens имеют значение «one». Теперь второй тернар оценивается следующим образом:

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

«один» является истинным (непустая строка), поэтому «два» – окончательный результат.

В основном интерпретатор оценивает это выражение слева направо, поэтому:

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

интерпретируется как

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

И выражение в паратезах оценивается как true, так как «одно» и «два» не являются нулевыми / о / другими формами ложных. Поэтому, если бы это выглядело так:

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

Он напечатает три. Чтобы он работал нормально, вы должны забыть о объединении тернарных операторов и использовать обычный ifs / switch для более сложной логики или, по крайней мере, использовать скобки, чтобы интерпретатор понял вашу логику и не выполнял проверку стандартным способом LTR:

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

Он работает правильно, когда вы используете скобки:

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

Я не понимаю его на 100%, но без скобок, для интерпретатора, утверждение должно выглядеть так:

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

результат первого условия, как представляется, возвращается в результате всей тройной операции.

Я думаю, что он оценивается следующим образом:

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

($ test == 'one'? 'one': $ test == 'two') отличен от нуля / null, поэтому 'two' является логическим выходом

если вы хотите, чтобы он работал правильно, напишите:

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

Документация PHP написана:

Примечание. Рекомендуется избегать тройных выражений . Поведение PHP при использовании нескольких тернарных операторов в одном выражении неочевидно:

Пример # 3 Неочевидное тернарное поведение

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

Если вы помещаете скобки вокруг ложного оператора, он печатает one :

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

Тернарные операторы выполняются в порядке появления, поэтому у вас действительно есть:

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

Вложенные троичные операции являются грубыми! Вышеприведенное объяснение показывает, почему.

В основном это логика:

 is $test == 'one' if TRUE then echo 'one' else is $test == 'two' if TRUE then echo 'two' else echo three