вложенная тройная проблема php: тройной вывод! = if – else

Я достаточно способен использовать PHP-тернарный оператор. Однако я попал в блокпост при попытке выяснить, почему приведенный ниже код не соответствует эквивалентной структуре if-else. Тест проводился три раза по разным числам. Выход для каждой структуры ниже кода.

троичной:

$decimal_places = ($max <= 1) ? 2 : ($max > 3) ? 0 : 1; 

Тройной выход:

max: -100000 decimal: 0

макс: 0.48 дробный: 0

max: 0,15 десятичных знаков: 0

Если еще

 if($max <= 1) $decimal_places = 2; elseif($max > 3) $decimal_places = 0; else $decimal_places = 1; 

If-Else Output:

max: -100000 десятичная: 2

макс: 0,48 десятичный: 2

макс: 0,15 дробный: 2

Может кто-нибудь, пожалуйста, скажите мне, почему эти две контрольные структуры не выводят одни и те же данные?

Solutions Collecting From Web of "вложенная тройная проблема php: тройной вывод! = if – else"

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

 $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); // Another way of looking at it $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 

В противном случае ваше тернарное выражение оценивается слева направо, в результате чего:

 $decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; // Another way of looking at it $decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; 

Который, переведенный в if-else, становится следующим:

 if ($max <= 1) $cond = 2; else $cond = ($max > 3); if ($cond) $decimal_places = 0; else $decimal_places = 1; 

Поэтому $decimal_places заканчивается как 0 для всех значений $max за исключением 2 , и в этом случае он оценивается в 1 .

Код выполняется как

 $decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; 

поэтому вы никогда не получите 2 и 1 только при 1 < $max <=3 . Это связано с тем, что условный оператор лево-ассоциативный . Решение. Поместите скобки, чтобы убедиться, что нужный вам порядок закодирован:

 $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 

Просто поставьте скобку, и все будет хорошо, вот так:

  $decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 

Как указывали другие, используйте paranthesis.
Однако, если вы действительно хотите сделать его доступным для чтения, то об этом:

 $decimal_places = ($max <= 1) ? 2 : ( ($max > 3) ? 0 : ( 1 )); 

Это все еще выглядит очень неудобно, но эта неловкость имеет правильную форму, поэтому с ней легче жить.

 $drink = 'wine'; return ($drink === 'wine') ? 'vinyard' : ( ($drink === 'beer') ? 'brewery' : ( ($drink === 'juice') ? 'apple tree' : ( ($drink === 'coffee') ? 'coffeebeans' : ( 'other' )))); 

Конечно, вы могли бы опустить последнюю пару скобок, но это сделало бы ее менее регулярной.