嵌套三元语句

时间:2011-10-04 20:28:57

标签: php if-statement ternary-operator

我想知道为什么这很奇怪。我知道区别在于分组,但相比之下它是否重要?

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';
   $i++;
}

返回

last_row
none
none
last_row

$i = 0;
foreach ($items as $item) {
   echo ($i == 0) ? 'first_row' : (($i == sizeof($feedbacks)-2) ? 'last_row' : 'none');
   $i++;
}

正确地返回

first_row
none
none
last_row

为什么会有区别?

4 个答案:

答案 0 :(得分:14)

要根据您的代码使用解释,缩小版本将为:

for ($i=0; $i<5; $i++) {
   echo $i == 0 ? 'first_row' : $i == 4 ? 'last_row' : 'none';
}

在PHP中,这相当于写作:

for ($i=0; $i<5; $i++) {
   echo ($i == 0 ? 'first_row' : $i == 4) ? 'last_row' : 'none';
}

首先,$i的值为0,因此第一个三元组返回'first_row',该字符串用作第二个三元组的条件 - 在布尔值中上下文评估为true - 因此返回'last_row'

如果重组:

for ($i=0; $i<5; $i++) {
   echo $i == 0 ? 'first_row' : ($i == 4 ? 'last_row' : 'none');
}

然后第一个三元的结果不会干扰第二个三元。

答案 1 :(得分:4)

来自official PHP documentation

  

“建议您避免”堆叠“三元表达式。在单个语句中使用多个三元运算符时PHP的行为是不明显的”

显然,尽管PHP的三元运算符(以及其大部分语法)都基于C,但由于某些原因,PHP决定make it left-associative,而在C和大多数基于它的语言中,{{3} }:

<强> C:

$ cat /tmp/foo.c
#include <stdio.h>
void main (void) { printf("%s\n", ( 1 ? "foo" : 0 ? "bar" : "baz" ) ); }

$ gcc -o /tmp/foo /tmp/foo.c; /tmp/foo
foo

<强>的Perl:

$ perl -e 'print ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
foo

<强>爪哇:

$ cat /tmp/foo.java
public class foo { public static void main(String[] args) {
    System.out.println( ( true ? "foo" : false ? "bar" : "baz" ) );
} }

$ javac -d /tmp /tmp/foo.java; java -cp /tmp foo
foo

<强> JavaScript的:

$ cat /tmp/foo.js
print( 1 ? "foo" : 0 ? "bar" : "baz" );

$ rhino -f /tmp/foo.js
foo

<强> PHP:

$ php -r 'echo ( 1 ? "foo" : 0 ? "bar" : "baz" ) . "\n";'
bar

所以,是的,我认为我们可以安全地得出结论,PHP在这方面也只是倒退了。

答案 2 :(得分:3)

请参阅example 3 on php.net

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

重要的部分是:

  

这是因为三元表达式从左到右进行评估

答案 3 :(得分:0)

看看JRL提供的答案。为了更清楚你的例子发生了什么,你应该明白你的表达式是这样评估的:

echo (($i == 0) ? 'first_row' : ($i == sizeof($feedbacks)-2)) ? 'last_row' : 'none';

所以当$i == 0你的陈述基本上变成了这个:

echo 'first_row' ? 'last_row' : 'none';

由于'first_row'评估为true,您的'last_row'$i == 0时返回的结果。当$i不等于零时,您的陈述基本上就变为:

echo ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none';