2010-04-17 19 views
14

me pidieron para llevar a cabo esta operación de utilización operador ternario:operación ternaria inusual

$test='one'; 

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

que imprime dos (comprobarse utilizando php).

Todavía no estoy seguro de la lógica para esto. Por favor, ¿alguien puede decirme la lógica para esto?

+3

oh mi ... mis ojos ... están quemando .... no puede ser invisible ... es –

+0

no es tan malo. En otros idiomas, esto sería un modismo. En PHP, gracias a su asociatividad de operador mal elegida, es una trampa. – bobince

+0

@bobince lo probaste en otros idiomas o simplemente asumiendo este – nik

Respuesta

15

Bueno, el? y: tienen la misma prioridad, por lo que PHP analizará izquierda a derecha evaluación de cada bit, a su vez:

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

Primeros $test == 'one' vuelve verdadera, por lo que los primeros parens tienen un valor 'uno'. Ahora el segundo ternario se evalúa como esto:

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

'uno' es verdadera (una cadena no vacío), por lo que 'dos' es el resultado final.

+0

Esta es la explicación correcta más corta :) +1. –

+0

rite dijo Pekka – nik

+0

+1 por brevedad y claridad de explicación (una combinación difícil) –

1

de PHP documentation dice:

Nota: Se recomienda que se evite "apilamiento" expresiones ternarias. El comportamiento de PHP cuando se utiliza más de un operador ternario en una sola sentencia no es obvia:

Ejemplo # 3 no evidente Comportamiento 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. 
?> 

Si se pone entre paréntesis alrededor de la declaración falsa, se imprime one:

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

anidado ternary operations are gross! La explicación anterior muestra por qué.

Básicamente esta es la lógica:

is $test == 'one' 

    if TRUE then echo 'one' 

    else is $test == 'two' 

     if TRUE then echo 'two' 

     else echo three 
+0

Creo que está en el camino correcto y tiene la mejor explicación, pero su lógica aún no se suma, ya que no está produciendo 'one' –

+0

La explicación de Filix Kling responde esa pregunta, aunque no tiene sentido por qué se necesitan paréntesis. –

5

funciona correctamente cuando se utiliza paréntesis:

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

que no lo entiende al 100% pero sin paréntesis, a la intérprete, la declaración debe tener este aspecto:

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

el resultado de la primera condición parece ser devuelto como resultado de toda la operación ternaria.

1

que piensan que no se evalúa del siguiente modo:

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

($ test == 'uno' 'uno':? $ Test == 'dos') es distinto de cero/nula, por lo que ' dos' es la salida lógica

si quieres que funcione correctamente, escribir:

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

Básicamente intérprete evalúa esta expresión de izquierda a derecha, por lo que:

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

se interpreta como

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

Y la expresión en paratheses como resultado true, ya que tanto 'uno' y 'dos 'no son nulos/o/otra forma de falso. lo tanto, si se vería así:

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

Sería imprimir tres. Para que funcione bien, debe olvidarse de combinar operadores ternarios, y usar ifs/switch regular para una lógica más complicada, o al menos usar los corchetes, para que el intérprete comprenda su lógica, y no realice la comprobación en modo LTR estándar:

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

Exactamente, estaba a punto de publicarlo, lo encontré en la documentación de php. :) –

1

operadores ternarios son ejecutados por orden de aparición, así que tienes:

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