2010-04-17 22 views
14

我被要求執行三元運營商利用這一操作:不尋常的三元操作

$test='one'; 

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

它打印兩(使用PHP檢查)。

我仍然不確定這個邏輯。請,任何人都可以告訴我這個邏輯。

+3

哦,我......我的眼睛......在燃燒....它不能是看不見的...... – 2010-04-17 14:58:52

+0

這是不是那麼糟糕。在其他語言中,這將是一個成語。在PHP中,由於其選擇較差的操作符關聯性,這是一個陷阱。 – bobince 2010-04-17 15:11:16

+0

@bobince你是否用其他語言試過,或者你只是假設這個 – nik 2010-04-17 15:35:26

回答

15

好了,?和:具有相同的優先級,那麼PHP將解析從左到右評估依次對每個位:

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

首先$test == 'one'返回true,所以第一個括號具有價值「一」。現在第二個三元評價是這樣的:

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

「一」爲真(非空字符串),所以「二」是最終結果。

+0

這是最簡單的正確解釋:) +1。 – 2010-04-17 15:55:54

+0

儀式說佩克 – nik 2010-04-19 05:58:29

+0

爲簡潔明瞭的解釋(一個困難的組合) – 2010-10-06 15:03:47

1

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'); 
0

嵌套三元操作很糟!以上解釋說明了原因。

基本上是這樣的邏輯:

is $test == 'one' 

    if TRUE then echo 'one' 

    else is $test == 'two' 

     if TRUE then echo 'two' 

     else echo three 
+0

我認爲你是在正確的軌道上,並有最好的解釋,但你的邏輯沒有加起來,因爲它不輸出'一個' – 2010-04-17 14:37:11

+0

Filix Kling的解釋回答了這個問題,儘管爲什麼需要括號是沒有意義的。 – 2010-04-17 14:38:22

5

它正常工作,當您使用括號:

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

我不明白100%,但不帶括號,給解釋,聲明一定是這樣的:

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

第一條件的結果似乎是作爲結果返回整個三元操作。

1

我認爲這是評價是這樣的:

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

($測試== '一' '一':$測試== '兩節')是非零/零,因此「二」是邏輯輸出

如果你想讓它才能正常工作

,寫:

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

基本上解釋器評估該表達從左至右,所以:

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

被解釋爲

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

而在paratheses表達式評估爲真,因爲兩個「一」和「二'不是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... 
} 
+0

準確地說,我即將發佈它,我發現它在PHP文檔。 :) – 2010-04-17 14:57:31

1

三元運營商都在出場順序執行的,所以你真的有:

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