2010-04-17 11 views
14

mi è stato chiesto di eseguire questa operazione di utilizzo operatore ternario:insolita operazione ternaria

$test='one'; 

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

che stampa due (controllato tramite php).

Non sono ancora sicuro della logica per questo. Per favore, qualcuno può dirmi la logica per questo.

+3

oh mio ... i miei occhi ... stanno bruciando .... non può essere invisibile ... –

+0

E ' non così male. In altre lingue, questo sarebbe un idioma. In PHP, grazie alla sua associatività dell'operatore scelta male, è una trappola. – bobince

+0

@bobince l'hai provato in altre lingue o stai assumendo questo – nik

risposta

15

Ebbene, il? e: hanno uguale precedenza, in modo da PHP Parse sinistra a destra valutare ogni bit a sua volta:

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

First $test == 'one' restituisce vero, così le prime parentesi hanno valore 'uno'. Ora la seconda ternario è valutato in questo:

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

'uno' è vero (una stringa non vuota), in modo da 'due' è il risultato finale.

+0

Questa è la spiegazione corretta più breve :) +1. –

+0

rite detto Pekka – nik

+0

+1 per brevità e chiarezza di spiegazione (una combinazione difficile) –

1

PHP'S documentation dice:

Nota: Si consiglia di evitare di "stacking" espressioni ternari. il comportamento di PHP quando si utilizza più di un operatore ternario all'interno di una singola istruzione non è ovvia:

Esempio # 3 non ovvia Comportamento ternario

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

Se si mette tra parentesi intorno alla falsa dichiarazione, stampa one:

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

Le operazioni ternarie annidate sono lorde! La spiegazione sopra mostra perché.

Fondamentalmente questo è la logica:

is $test == 'one' 

    if TRUE then echo 'one' 

    else is $test == 'two' 

     if TRUE then echo 'two' 

     else echo three 
+0

Penso che tu sia sulla strada giusta e abbia la migliore spiegazione, ma la tua logica non si somma ancora, dato che non emette 'one' –

+0

La spiegazione di Filix Kling risponde a questa domanda anche se non ha senso perché siano necessarie le parentesi. –

5

E funziona correttamente quando si utilizza parentesi:

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

io non lo capisco al 100%, ma senza parentesi, per l'interprete, la dichiarazione deve apparire così:

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

il risultato della prima condizione sembra essere restituito come risultato dell'intera operazione ternaria.

1

Penso che sia valutato in questo modo:

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

($ test == 'uno' 'uno':? $ Test == 'due') è diverso da zero/null, cosi ' due' è uscita logica

se si vuole farlo funzionare correttamente, scrivere:

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

Fondamentalmente interprete la valuta questa espressione da sinistra a destra, in modo da:

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

viene interpretato come

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

E l'espressione in paratheses restituisce true, dal momento che entrambi 'uno' e 'due 'non sono null/o/altra forma di falso. Quindi, se sarebbe simile:

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

Sarebbe stampare tre. Per far sì che funzioni correttamente, dovresti dimenticare di combinare gli operatori ternari e utilizzare ifs/switch regolari per una logica più complicata, o almeno usare le parentesi, affinché l'interprete comprenda la tua logica e non esegua il controllo in modalità LTR standard:

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

Esattamente, stavo per postarlo, l'ho trovato nella documentazione php. :) –

1

Gli operatori ternari vengono eseguiti in ordine di apparizione in modo da avere davvero:

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