2011-01-26 89 views
5

我相当有能力使用PHP三元运算符。然而,我试图找出为什么下面的代码与if-else等价结构不匹配时遇到了一个障碍。测试在不同的数字上运行三次。每个结构的输出在代码下面。嵌套的php三元麻烦:三元输出!= if - else

三元:

$decimal_places = ($max <= 1) ? 2 : ($max > 3) ? 0 : 1; 

三元输出:

最大:-100000十进制:0

最大:0.48十进制:0

最大:0.15十进制:0

的if-else

if($max <= 1) 
$decimal_places = 2; 
elseif($max > 3) 
$decimal_places = 0; 
else 
$decimal_places = 1; 

的if-else输出:

最大:-100000十进制:2

最大:0.48十进制:2

最大:0.15十进制:2

任何人都可以告诉我为什么这两个控件结构不输出相同的数据?

+4

嵌套三元运算符不是一个好主意的原因之一 – 2011-01-26 17:04:39

+1

它们并不完全等价,你知道的。整个elseif将在三元结构中短路。它们也不是要嵌套的。 – 2011-01-26 17:05:22

回答

18

你的右手边三元表达式需要被包裹在括号所以它会通过自身作为一个单一的公式进行计算:

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 

// Another way of looking at it 
$decimal_places = ($max <= 1) 
       ? 2 
       : (($max > 3) ? 0 : 1); 

否则你的三元表达式的值由左到右,导致:

$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; 

// Another way of looking at it 
$decimal_places = (($max <= 1) ? 2 : ($max > 3)) 
       ? 0 
       : 1; 

其中,翻译成的if-else,成为本:

if ($max <= 1) 
    $cond = 2; 
else 
    $cond = ($max > 3); 

if ($cond) 
    $decimal_places = 0; 
else 
    $decimal_places = 1; 

因此$decimal_places最终成为0以外2$max所有值,在这种情况下,它的计算结果为1

2

的代码为

$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; 

执行的,所以你永远不会得到2和1只在1 < $max <=3。这是因为条件运算符是left-associative。解决方案:将括号,以确保您想要的顺序编码:

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 
1

只要把括号,你就可以了,就像这样:

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 
1

正如其他人所指出的,使用paranthesis。
但是,如果你真的想使它可读,你看这个:

$decimal_places = 
    ($max <= 1) ? 2 : (
    ($max > 3) ? 0 : (
    1 
)); 

这看起来还是超级尴尬,但这种尴尬有一个规则的形状,所以它更容易忍受。

$drink = 'wine'; 
return 
    ($drink === 'wine') ? 'vinyard' : (
    ($drink === 'beer') ? 'brewery' : (
    ($drink === 'juice') ? 'apple tree' : (
    ($drink === 'coffee') ? 'coffeebeans' : (
    'other' 
)))); 

你当然可以省略最后一对括号,但这会使它看起来不太经常。