Вот что я написал:
$Myprovince = ( ($province == 6) ? "city-1" : ($province == 7) ? "city-2" : ($province == 8) ? "city-3" : ($province == 30) ? "city-4" : "out of borders" );
Но для каждого поля я получил значение city-4
. Я хочу использовать тройные операторы вместо switch/if
потому что я хочу поэкспериментировать и посмотреть, как это будет сделано.
В чем проблема с этим кодом?
Другие уже предложили правильный способ сделать это, но если вы действительно хотите использовать тернарный оператор, вам нужно использовать скобки как:
$province = 7; $Myprovince = ( ($province == 6) ? "city-1" : (($province == 7) ? "city-2" : (($province == 8) ? "city-3" : (($province == 30) ? "city-4" : "out of borders"))) );
Смотрите на идеон
Тернарный оператор оценивается слева направо. Поэтому, если вы не группируете выражения правильно, вы получите неожиданный результат.
Совет PHP [docs] :
Рекомендуется избегать «укладки» тернарных выражений. Поведение PHP при использовании нескольких трёхмерных операторов в одном выражении неочевидно.
Ваш код фактически оценивается как:
( ( ( $province == 6 ? "city-1" : $province == 7 ) ? "city-2" : $province == 8 ) ? "city-3" : $province == 30 ) ? "city-4" : "out of borders";
где это должно быть
$province == 6 ? "city-1" : ( $province == 7 ? "city-2" : ( $province == 8 ? "city-3" : ( $province == 30 ? "city-4" : "out of borders" ) ) );
Этот код может выглядеть отлично, но кто-то его прочитает, и им потребуется больше времени, чем нужно, чтобы понять, что делает этот код.
Вам было бы лучше с чем-то вроде этого:
$map = array( 6 = >'city-1', 7 => 'city-2', 8 => 'city-3', 30 => 'city-4'); $Myprovince = "out of borders"; if(array_key_exists($province, $map)) { $Myprovince = $map[$province]; }
Или как @Jonah упомянул в своем комментарии:
$Myprovince = isset($map[$province]) ? $map[$province] : 'out of borders';
Не злоупотребляйте тернарным оператором для такого рода вещей. Это делает отладки почти невозможным. Почему бы не сделать что-то вроде
switch($province) { case 6: $Myprovince = "city-1"; break; case 7: ... }
или просто прикованный, если / then / else
if ($province == 6) { $Myprovince = "city-1"; } elseif ($province = ...) { ... }
Некоторые люди предложили использовать оператор switch или оператор if / else. Но вместо этого я бы использовал массив, чтобы упростить его и упростить для чтения:
$provinces = array ( 6 => 'city-1', 7 => 'city-2', 8 => 'city-3', 30 => 'city-4' ); // then you can call: $Myprovince = isset($provinces[$province]) ? $provinces[$province] : 'out of borders';
В конце концов, код будет легче управлять. Может быть, вам захочется добавить эти сопоставления между городами из базы данных в один прекрасный день .. и т. Д. Это будет сложно поддерживать с кучей операторов switch / case.
Попробуйте еще скобки:
$Myprovince = ( ($province == 6) ? "city-1" : (($province == 7) ? "city-2" : (($province == 8) ? "city-3" : (($province == 30) ? "city-4" : "out of borders" ))));
У вашего кода есть проблема с приоритетом троичного оператора.
Но я думаю, что вы действительно должны отказаться от этого оператора и попытаться использовать switch
.
Я понимаю, что это вопрос о PHP, но поскольку это всего лишь учебное упражнение, я думал, что вам может быть интересно узнать, что Ruby и Javascript действительно ведут себя так, как вы ожидаете.
Рубин:
ree-1.8.7-2012.02 :009 > def foo x ree-1.8.7-2012.02 :010?> x == 1 ? "city 1" : x == 2 ? "city 2" : "out of borders" ree-1.8.7-2012.02 :011?> end => nil ree-1.8.7-2012.02 :012 > foo 1 => "city 1" ree-1.8.7-2012.02 :013 > foo 2 => "city 2" ree-1.8.7-2012.02 :014 > foo 3 => "out of borders"
Javascript:
> function f(x) { return x == 1 ? "city 1" : x == 2 ? "city 2" : "out of borders"; } undefined > f(1) "city 1" > f(2) "city 2" > f(3) "out of borders"
Вместо этого используйте переключатель. Тернарные операторы действительно не должны использоваться для более чем одного условия, так как они быстро становятся очень трудными для понимания.
switch ($province) { case 6: $Myprovince = 'city-1'; break; case 7: $Myprovince = 'city-2'; break; case 8: $Myprovince = 'city-3'; break; case 30: $Myprovince = 'city-4'; break; default: $Myprovince = 'out of borders'; }