Понимание вложенного PHP тернарного оператора
Я не понимаю, как этот вывод ("four
") приходит?
$a = 2;
echo
$a == 1 ? 'one' :
$a == 2 ? 'two' :
$a == 3 ? 'three' :
$a == 5 ? 'four' :
'other'
;
// prints 'four'
Я не понимаю почемуfour
"печатается.
4 ответа
Вы должны заключить в скобки троичные условия:
<?php
for ($a=0; $a < 7; $a++) {
echo (
$a == 1 ? 'one' :
($a == 2 ? 'two' :
($a == 3 ? 'three' :
($a == 5 ? 'four' : 'other'))));
echo "\n";
// prints 'four'
}
exit;
?>
возвращает:
other
one
two
three
other
four
other
как и следовало ожидать.
См. Примечание внизу "Тернарные операторы" в справке PHP "Тернарные операторы".
Выражения оцениваются слева направо. Итак, вы на самом деле получаете:
echo (
((($a == 1 ? 'one' : $a == 2)
? 'two' : $a == 3) ? 'three' :
$a == 5) ? 'four' : 'other');
Таким образом, для $a=2
, ты получаешь:
echo (
((($a==2) ? 'two' : $a == 3) ? 'three' :
$a == 5) ? 'four' : 'other');
а потом
echo (
((true ? 'two' : $a == 3) ? 'three' :
$a == 5) ? 'four' : 'other');
а потом
echo (
('two' ? 'three' : $a == 5) ? 'four' : 'other');
а потом
echo (
'three' ? 'four' : 'other');
так что echo 'four'
,
Помните, что PHP динамически типизирован и рассматривает любые ненулевые ненулевые значения как ИСТИНА.
На странице " Операторы сравнения" в Руководстве по PHP они объясняют, что поведение PHP "неочевидно" при вложении (укладке) троичных операторов.
Код, который вы написали, выглядит так:
$a = 2;
echo
((($a == 1 ? 'one' :
$a == 2) ? 'two' :
$a == 3) ? 'three' :
$a == 5) ? 'four' :
'other'
;
// prints 'four'
Как $a
2 и оба 'two'
а также 'three'
ИСТИНА, вы получитеfour
"В результате, как вы больше не сравниваете, если 'four'
ВЕРНО или нет.
Если вы хотите изменить это, вы должны поставить скобки в разных местах [также отмечено: BeingSimpler и MGwynne]:
$a = 2;
echo
($a == 1 ? 'one' :
($a == 2 ? 'two' :
($a == 3 ? 'three' :
($a == 5 ? 'four' :
'other'))))
;
// prints 'two'
Проблема с условиями группировки, просто нужно добавить скобки для их разделения.
$a = 2;
echo (
$a == 1 ? 'one' :
($a == 2 ? 'two' :
($a == 3 ? 'three' :
($a == 5 ? 'four' : 'other'))));
echo "\n";
// prints 'four'
exit;
Решаемые.
Это то, что я придумал, чтобы помочь себе понять левую и правую ассоциативность для троичного оператора.
// PHP
$a = "T";
$vehicle = $a == "B" ? "bus" :
$a == "A" ? "airplane" :
$a == "T" ? "train" :
$a == "C" ? "car" :
$a == "H" ? "horse" : "feet";
// (as seen by the PHP interpreter)
// INITIAL EXPRESSION: ((((($a == "B" ? "bus" : $a == "A") ? "airplane" : $a == "T") ? "train" : $a == "C") ? "car" : $a == "H") ? "horse" : "feet");
// STEP 1: (((((FALSE ? "bus" : FALSE) ? "airplane" : TRUE) ? "train" : FALSE) ? "car" : FALSE) ? "horse" : "feet")
// STEP 2: ((((FALSE ? "airplane" : TRUE) ? "train" : FALSE) ? "car" : FALSE) ? "horse" : "feet")
// STEP 3: (((TRUE ? "train" : FALSE) ? "car" : FALSE) ? "horse" : "feet")
// STEP 4: (("train" ? "car" : FALSE) ? "horse" : "feet")
// STEP 5: ("car" ? "horse" : "feet")
// FINAL EVALUATION: ("horse")
// If you used the initial expression here (with the parenthesis) in a different language, it would also evaluate to "horse."
echo $vehicle; // gives us "horse"
Это в отличие от:
// EVERY OTHER LANGUAGE
var a = "T";
var vehicle = a == "B" ? "bus" :
a == "A" ? "airplane" :
a == "T" ? "train" :
a == "C" ? "car" :
a == "H" ? "horse" : "feet";
// (as seen by the other language's interpreter)
// INITIAL EXPRESSION: (a == "B" ? "bus" : (a == "A" ? "airplane" : (a == "T" ? "train" : (a == "C" ? "car" : (a == "H" ? "horse" : "feet")))));
// STEP 1: (FALSE ? "bus" : (FALSE ? "airplane" : (TRUE ? "train" : (FALSE ? "car" : (FALSE ? "horse" : "feet")))))
// STEP 2: (FALSE ? "bus" : (FALSE ? "airplane" : (TRUE ? "train" : (FALSE ? "car" : "feet"))))
// STEP 3: (FALSE ? "bus" : (FALSE ? "airplane" : (TRUE ? "train" : "feet")))
// STEP 4: (FALSE ? "bus" : (FALSE ? "airplane" : "train"))
// STEP 5: (FALSE ? "bus" : "train")
// FINAL EVALUATION: ("train")
// If you used the initial expression here (with the parenthesis) in PHP, it would also evaluate to "train."
console.log(vehicle); // gives us "train"
Если вы заметили, что в примере PHP самое внутреннее выражение находится слева, а во втором примере самое внутреннее выражение справа. Каждый шаг оценивает следующее самое внутреннее выражение, пока не будет единственного результата. Скобки явно очень важны, если вы собираетесь вкладывать троичные операции в PHP!