【问题标题】:Understanding nested PHP ternary operator [duplicate]了解嵌套的 PHP 三元运算符 [重复]
【发布时间】:2011-09-07 15:14:51
【问题描述】:

我不明白那个输出 ("four") 是怎么来的?

$a = 2;

echo
  $a == 1 ? 'one'   :
  $a == 2 ? 'two'   :
  $a == 3 ? 'three' :
  $a == 5 ? 'four'  : 
    'other'  
  ;

// prints 'four'

我不明白为什么会打印“four”。

【问题讨论】:

  • @riky: 是的,但是$a=2 在他的代码中......
  • YA 所以根据您的登录,它将打印“两个”。你能解释一下你到底想要什么吗?
  • == 运算符的优先级高于 ternar 运算符。所以必须使用方括号进行分组。 php.net/manual/en/language.operators.precedence.php
  • 除了完全不可读之外,您还应该避免堆叠三元运算符。请参阅手册中的注释de2.php.net/manual/en/language.operators.comparison.php
  • 在 C/C++/Java 中你会得到“两个”。 PHP 不同的实际原因是因为 PHP 从左到右而不是从右到左处理 ?: 关联性。这是众所周知的 PHP 错误设计。请参阅 this explanationthat criticism。这个问题不是题外话,因为这是一个真实且有问题的 PHP 优先级问题。

标签: php ternary-operator operator-precedence


【解决方案1】:

你需要把三元条件括起来:

<?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 Ternary operator help“三元运算符”底部的注释。

从左到右计算表达式。所以你实际上得到了:

  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 是动态类型的,并将任何非零非空值视为 TRUE。

【讨论】:

  • 因为 == 运算符比 ternar 运算符具有更高的优先级,并且会失败;)
  • err,你打了我将近 3 分钟,但系统根本没有注意到我,grrr。
  • 真棒解释..即使我没有得到如何回答这个sn-p。谢谢老兄..
  • 与其他语言中的三元运算符相比,这是完全相反的行为,例如:C/C++ 或 Java。甚至 JavaScript 也以正确(预期)的方式做到这一点。无论如何,如PHP手册中所述,不建议使用嵌套三元表达式
【解决方案2】:

the Comparison Operators page in the PHP Manual 他们解释说,当嵌套(堆叠)三元运算符时,PHP 的行为是"non-obvious"

你写的代码是这样的:

$a = 2;

echo
  ((($a == 1  ? 'one'   :
     $a == 2) ? 'two'   :
     $a == 3) ? 'three' :
     $a == 5) ? 'four'  : 
       'other'
  ;

// prints 'four'

由于 $a 为 2 且 'two''three' 均为 TRUE,因此您将得到“four”作为结果,因为您不再比较 'four' 是否为 TRUE .

如果你想改变它,你必须把括号放在不同的地方[也注意到:BeingSimpler 和 MGwynne]:

$a = 2;
echo 
  ($a == 1 ? 'one'   :
  ($a == 2 ? 'two'   :
  ($a == 3 ? 'three' :
  ($a == 5 ? 'four'  : 
     'other'))))
  ;

// prints 'two'

【讨论】:

  • @BeingSimpler: 找不到链接 ;) 别担心我没有复制你的代码 :)
  • 我知道你没有,系统延迟了一点。我上面的答案实际上比 MGwynne 的答案晚了 3 分钟,但是当我发布时,它出现在同一时间。
【解决方案3】:

分组条件的问题,只需要加括号分隔即可。

$a = 2;
echo (
$a == 1 ? 'one' :
($a == 2 ? 'two' :
($a == 3 ? 'three' :
($a == 5 ? 'four' : 'other'))));
echo "\n";
// prints 'four'
exit;

解决了。

【讨论】:

    【解决方案4】:

    这是我想出的帮助自己理解三元运算符的左与右关联性的方法。

    // 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 中嵌套三元运算,括号显然非常重要!

    【讨论】:

      猜你喜欢
      • 2021-05-27
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 2016-07-18
      • 2013-01-21
      • 2011-10-29
      相关资源
      最近更新 更多