46

PHP のマニュアルでは、"Operators"の下に次のような "ユーザー投稿メモ" があります。

php では、三項演算子 ?: は C や C++ では右結合性を持つのとは異なり、左結合性を持つことに注意してください。

次のようなコードを書くことはできません (C/C++ で慣れているかもしれません)。

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

実際に試してみると、本当に印刷されfourます。ただし、その背後にある理由を理解できず、印刷する必要があると感じていますtwoまたはother.

ここで何が起こっているのか、なぜ「4」と表示されているのか説明してもらえますか?

4

5 に答える 5

64

正常な言語では、三項演算子は右結合であるため、コードは次のように解釈されると予想されます。

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

ただし、PHP の三項演算子は奇妙に左結合であるため、コードは実際には次のようになります。

<?php
$a = 2;
echo (((($a == 1  ? 'one' :
         $a == 2) ? 'two' :
         $a == 3) ? 'three' :
         $a == 4) ? 'four' : 'other');   # prints 'four'

それでも明確でない場合、評価は次のようになります。

echo ((((FALSE    ? 'one' :
         TRUE)    ? 'two' :
         $a == 3) ? 'three' :
         $a == 4) ? 'four' : 'other');

echo ((( TRUE     ? 'two' :
         $a == 3) ? 'three' :
         $a == 4) ? 'four' : 'other');

echo ((  'two'    ? 'three' :
         $a == 4) ? 'four' : 'other');

echo (    'three' ? 'four' : 'other');

echo 'four';
于 2016-07-06T18:24:29.140 に答える
25

式全体が であるかのように評価されるため(......) ? 'four' : 'other'です。最初の要素はおそらく真実であるため、 が得られます'four'。が正しい結合性を持つ健全な言語で?:は、式全体が$a == 1 ? 'one' : (......)であるか$aのように評価され1ます。

于 2013-12-13T04:39:20.243 に答える
0

括弧を追加すると、問題は解決します。次の例を見てください:
括弧がない場合、点数が 50 を超える場合、成績は常に D になりますが、点数 <= 49 の場合は問題
なく機能します。プログラムが正常に機能するようにするために、括弧を追加しました。このように入力すると、括弧をいくつ入力すればよいかを非常に簡単に知ることができます。

<?php
 $marks_obtained = 65;
 $grade = null;
 //Use parentheses () otherwise the final grade shown will be wrong.
//Excluding the first line, for each additional line, 
//we add a parenthesis at the beginning of each line and a parenthesis at the end of the statement.
echo $grade = $marks_obtained >= 90 && $marks_obtained <= 100 ?  "A+"
              : ($marks_obtained <= 89 && $marks_obtained >= 80 ? "A"
              : ($marks_obtained <= 79 && $marks_obtained >= 70 ? "B"
              : ($marks_obtained <= 69 && $marks_obtained >= 60 ? "C"
              : ($marks_obtained <= 59 && $marks_obtained >= 50 ? "D"
              :                                                     "F"))))
?>
于 2014-10-16T18:57:45.070 に答える