【问题标题】:unusual ternary operation异常三元运算
【发布时间】:2011-02-09 03:53:19
【问题描述】:

我被要求执行这个三元运算符使用的操作:

$test='one';

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

打印两个(使用 php 检查)。

我仍然不确定这样做的逻辑。拜托,谁能告诉我这个的逻辑。

【问题讨论】:

  • 哦,我的……我的眼睛……在燃烧……它不可能看不见……
  • 还不错。在其他语言中,这将是一个成语。在 PHP 中,由于其选择不当的运算符关联性,这是一个陷阱。
  • @bobince 你用其他语言试过吗,或者你只是假设这个
  • C 和大多数基于其语法的语言(C#、Java、JavaScript...)给出one。 Wiki(公平地说,IMO)将 PHP 的行为描述为“语言语法中的不幸错误”。 en.wikipedia.org/wiki/%3F:#PHP
  • 我想我们大多数人都明白了,对不起,但只能选择 1

标签: php logic ternary-operator logical-operators


【解决方案1】:

嗯,? and : 具有相同的优先级,因此 PHP 会从左到右依次解析每个位:

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

第一个$test == 'one' 返回真,所以第一个括号的值为'one'。现在第二个三元的评估如下:

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

'one' 为真(非空字符串),所以 'two' 是最终结果。

【讨论】:

  • +1 简洁明了的解释(一个困难的组合)
【解决方案2】:

解释器基本上从左到右计算这个表达式,所以:

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

被解释为

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

并且括号中的表达式计算结果为真,因为“一”和“二”都不是 null/o/其他形式的假。 所以如果它看起来像:

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

【讨论】:

  • 没错,我正要发,我在php文档里找到了。 :)
【解决方案3】:

当你使用括号时它可以正常工作:

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

我没有 100% 理解它,但没有括号,对于解释器来说,语句必须是这样的:

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

第一个条件的结果似乎是作为整个三元运算的结果返回的。

【讨论】:

    【解决方案4】:

    我认为是这样评价的:

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

    ($test == 'one' ? 'one' : $test == 'two') 非零/空,所以 'two' 是逻辑输出

    如果你想让它正常工作,写:

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

    【讨论】:

      【解决方案5】:

      PHP 的 documentation 说:

      注意:建议您避免“堆叠”三元表达式。在单个语句中使用多个三元运算符时 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');
      

      【讨论】:

        【解决方案6】:

        三元运算符按出现的顺序执行,所以你真的有:

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

        【讨论】:

          【解决方案7】:

          嵌套的三元运算太恶心了!上面的解释说明了原因。

          基本上是这样的逻辑:

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

          【讨论】:

          • 我认为你在正确的轨道上并且有最好的解释,但你的逻辑还没有加起来,因为它没有输出one
          • Filix Kling 的解释回答了这个问题,尽管为什么需要括号没有意义。
          猜你喜欢
          • 2020-05-10
          • 1970-01-01
          • 2016-01-08
          • 1970-01-01
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          • 2017-05-10
          • 1970-01-01
          相关资源
          最近更新 更多