2011-10-04 9 views
8

なぜこれが奇妙に動作するのだろうか。私は違いがグループ化していることを理解していますが、それは比較で重要ですか?ネストされた三項文

$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 

なぜ違いがあるのでしょうか?

答えて

13

あなたのコードに基づいた説明を使用するには、スケールダウンバージョンは次のようになります。

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'; 
} 

$i0の価値を持っているので、最初の三元に戻りその文字列は第2の三項の条件として使用されます。ブール値のコンテキストではtrueと評価され、したがって'last_row'が返されます。

あなたはそれを再グループ化した場合:

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

その後、最初の三元の結果は、二三元とは干渉しません。

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

重要な部分のビーイング:

三項式はofficial PHP documentationから左から右

4

に評価されるため、これは次のとおりです。

"三項式を「積み重ねる」ことは避けることをお勧めします。ひとつの文の中で複数の三項演算子を使用してPHPの振る舞いは、PHPの三項演算子が(とそうでないその構文の多くは)PHPをすることを決めたいくつかの理由で、Cに基づいているにもかかわらず、どうやら

「非自明ですmake it left-associativeは、Cおよび他のほとんどの言語でのに対しthe ternary operator is right-associative、それに基づく:

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 

のJava:

$ 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がこの点で(まったく)逆になっていると安全に結論づけることができると思います。

+0

他の言語の素敵なexemplesのアップウィートとphp:/ –

0

JRLの回答をご覧ください。

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

'first_row'trueに評価されているので:

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

だから、$i == 0あなたの文は、本質的に、このになったとき:あなたの例で何が起こっているか、あなたの表現のような評価をされていることを理解しておく必要があります詳細については明確にするために、あなたの'last_row'は、$i == 0と返された結果です。 $iはゼロあなたの文は、基本的にこれになっていないとき:

echo ($i == sizeof($feedbacks)-2) ? 'last_row' : 'none'; 
関連する問題