2010-04-17 4 views
14

on m'a demandé d'effectuer cette opération d'utilisation de l'opérateur ternaire:opération ternaire inhabituelle

$test='one'; 

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

qui imprime deux (vérifié en utilisant php).

Je ne suis pas encore sûr de la logique pour cela. S'il vous plaît, quelqu'un peut-il me dire la logique pour cela.

+3

oh mon ... mes yeux ... brûlent .... il ne peut pas être invisible ... il est –

+0

pas si mal. Dans d'autres langues, ce serait un idiome. En PHP, grâce à son associativité d'opérateur mal choisie, c'est un piège. – bobince

+0

@bobince a u essayé dans d'autres langues ou u r juste assumer cette – nik

Répondre

15

Eh bien, la? et: ont la même priorité, donc PHP Parse gauche à droite évaluer chaque bit à son tour:

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

First $test == 'one' renvoie true, donc les premiers parens ont une valeur 'un'. Maintenant, le deuxième ternaire est évalué comme suit:

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

« un » est vrai (une chaîne non vide), de sorte que « deux » est le résultat final.

+0

Ceci est l'explication correcte la plus courte :) +1. –

+0

rite dit Pekka – nik

+0

+1 par souci de concision et de clarté d'explication (une combinaison difficile) –

1

PHP'S documentation dit:

Note: Il est recommandé éviter "empiler" les expressions ternaires. Le comportement de PHP lors de l'utilisation de plus d'un opérateur ternaire dans une seule déclaration est non évidente:

Exemple # 3 ternaires non évidente Comportement

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

Si vous mettez entre parenthèses autour de la fausse déclaration, il imprime one:

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

Les opérations ternaires imbriquées sont grossières! L'explication ci-dessus montre pourquoi.

En gros, cela est la logique:

is $test == 'one' 

    if TRUE then echo 'one' 

    else is $test == 'two' 

     if TRUE then echo 'two' 

     else echo three 
+0

Je pense que vous êtes sur la bonne voie et ont la meilleure explication, mais votre logique ne correspond pas encore, car il ne fournir en sortie 'One' explication de –

+0

Filix Kling répond à cette question même si elle n'a pas de sens pourquoi les parenthèses sont nécessaires. –

5

Il fonctionne correctement lorsque vous utilisez entre parenthèses:

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

Je ne comprends pas 100% mais sans parenthèses, à l'interprète, la déclaration doit ressembler à ceci:

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

le résultat de la première condition semble être renvoyé comme résultat de toute l'opération ternaire.

1

Je pense qu'il est évalué comme suit:

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

(== de test $ 'un' 'un': == de test $ 'deux') est non nul/null, donc ' deux » est sortie logique

si vous voulez que cela fonctionne correctement, écrire:

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

Fondamentalement interprète évalue cette expression de gauche à droite, donc:

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

est interprété comme

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

Et l'expression dans paratheses est évaluée à vrai, puisque les deux 'un' et « deux 'ne sont pas null/o/autre forme de faux. Donc, si elle ressemblerait à ceci:

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

Il imprimerait trois. Pour le faire fonctionner bien, vous devriez oublier la combinaison des opérateurs ternaires, et utiliser ifs réguliers/commutateur pour une logique plus complexe, ou au moins utiliser les supports, pour l'interprète de comprendre votre logique, et non effectuer une vérification de manière standard RLT:

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

Exactement, j'étais sur le point de le publier, je l'ai trouvé dans la documentation php. :) –

1

opérateurs ternaires sont exécutés par ordre d'apparition si vous avez vraiment:

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