2010-12-21 22 views
6

El ejemplo siguiente es un extracto de http://php.net/manual/de/control-structures.switch.phpproblema con el interruptor condicional

<?php 
$totaltime = 0; 
switch ($totaltime) { 

    case ($totaltime < 1): 
     echo "That was fast!"; 
     break; 

    case ($totaltime > 1): 
     echo "Not fast!"; 
     break; 

    case ($totaltime > 10): 
     echo "That's slooooow"; 
     break; 
} 

?> 

que esperaba el resultado como "Eso fue rápido." Pero el resultado real es "¡No rápido!". Sería genial si alguien me puede explicar por qué?

Pero si agrego otra caja, case 0: echo "That was super fast!". Entonces está haciendo eco correctamente. es decir, "¡Eso fue súper rápido!". Por favor, ayúdame a usar la declaración de cambio condicional.

EDIT: -

Gracias a todos por sus respuestas. Soy capaz de superar el problema anterior modifyong interruptor ($ totalTime) para cambiar (1)

+0

= desactivar únicamente evaluar una vez, parece mal utilizado en él – ajreal

Respuesta

10

case ($totaltime < 1): significa 1 a PHP (esa ecuación devuelve verdadero)

case ($totaltime > 1): significa 0 a PHP (esa ecuación devuelve false)

Desde $totaltime es 0, se obtiene que la producción

En otras palabras PHP compara $totaltime al resultado de las comparaciones.

EDITAR EDITAR respecto de OP:

Usted necesita deshacerse de la switch() -statement. Solo lo usa para comparar fácilmente con diferentes valores y no usar expresiones adicionales con él.

me refiero a lo que está mal con

<?php 
$totaltime = 0; 

if ($totaltime < 1) { 
    echo "That was fast!"; 
} else if ($totaltime > 10) { 
    echo "That's slooooow"; 
} else if ($totaltime > 1) { 
    echo "Not fast!"; 
} 

?> 

EDIT: Tenga en cuenta que cambié las dos últimas sentencias if para que sea realmente funciona.

+0

- No hay ningún error en absoluto. Pero tengo cerca de 20 valores para los cuales necesito comparar y mostrar el error. Así que pensé que el cambio lo haría más legible en vez de IF. – satya

+0

@lucky: pero ¿entiende que es mucho más legible con un conjunto de declaraciones 'if()'? También significaría menos código, lo que daría lugar a menos errores (aunque esto es más bien una regla general). – sjngm

1

Parecería que se trata de un problema de conversión.

La primera declaración de caso se evaluará en cualquier otro que no sea 0, por lo que no se golpeará.

Pero la segunda declaración de caso evaluará a falso, que debe ser 0, que es igual a lo que ha establecido $ totaltime.

1

Lucky,

El modificador PHP es igual que la serie de sentencias IF. Los casos se evalúan como:

if($totaltime == ($totaltime < 1)) { 
    echo "That was fast!"; 
    break; 
} 
if($totaltime == ($totaltime > 1)) { 
    echo "Not fast!"; 
    break; 
} 
... 

Claramente 0 == false para segunda IF es verdadera y, por tanto, el resultado.

Gracias, Vikas.

2

No utiliza condicionales en las declaraciones case como ese, de forma no intuitiva de todos modos. Esto es lo que está pasando:

case ($totaltime < 1): // Evaluates to 1. $totaltime is not 1, so no match. 
    case ($totaltime > 1): // Evaluates to 0. $totaltime is 0, so match. 

Esencialmente usted está tratando de utilizar una construcción else if como una construcción switch, pero la funcionalidad no está allí.Los condicionales no se evalúan de la forma esperada (como lo harían en un bloque if), solo están buscando el primer bloque case que es igual al valor que se prueba en el bloque switch.

0

Otros han mencionado por qué ocurre esto (uso indebido de un condicional en el enunciado de caso), pero no han ofrecido alternativas. Switch está destinado a cubrir argumentos específicos como {0, 1, 2, 3..100, 101}, etc. Separa los argumentos o rangos específicos en lugar de realizar un simple if/else (como lo has usado). Puede volver a escribir sus argumentos para llevarlo a cabo sin embargo:

switch ($totaltime) { 

    case (0): 
     echo "That was fast!"; 
     break; 

    case (1..PHP_INT_MAX): 
     echo "Not fast!"; 
     break; 

    default: 
     echo "That's slooooow"; 
     break; 
} 

Aquí el .. permite un rango a ser cubierta, por lo que cualquier cosa de 1 a entero máximo está cubierta por ese caso. El 0 se maneja de forma explícita y todos los demás (re: < 0) están cubiertos por el caso predeterminado.

+0

+1, gracias por su respuesta. Esto es lo que estoy buscando. cuando $ totaltime = 10; da como resultado "Eso es slooooow"; en lugar de "¡No rápido!"; – satya

+0

-1 PHP no admite rangos como los utilizados en un conmutador/caja. Su 'caso (1..PHP_INT_MAX):' devolverá el valor concatenado de 1 y PHP_INT_MAX (12147483647). Supongo que hiciste demasiado Pascal últimamente y estás mezclando la sintaxis de PHP y Pascal: p. – wimvds

+0

@wimvds: Gracias por el comentario y la información. Creo que he estado pasando demasiado tiempo en otros idiomas últimamente. –

2

Odio a necro una publicación que ya está respondida, pero estoy bastante desconcertado, nadie tocó el método de cambio (verdadero).

No hay ventaja de la velocidad real de cualquiera de los métodos

En algunos casos, la conversión fue más rápido, otros el caso era más rápido, pero sólo por fracciones de un microsegundo (48.16 mu s vs 49,11 mu s cambian más rápido que si)

EDITAR

Y ahora veo el PO hizo lo mismo ...

<?php 
for ($totaltime = 0; $totaltime < 11; $totaltime += 0.5) { 
    switch (true) { 
     case ($totaltime < 1): 
      echo $totaltime . " That was fast!\n"; 
      break; 
     case ($totaltime < 10): 
      echo $totaltime . " Not fast!\n"; 
      break; 
     default: 
      echo $totaltime . " That's slooooow\n"; 
      break; 
    } 
} 

Resultados: https://3v4l.org/d71lZ

0 That was fast! 
0.5 That was fast! 
1 Not fast! 
1.5 Not fast! 
2 Not fast! 
2.5 Not fast! 
3 Not fast! 
3.5 Not fast! 
4 Not fast! 
4.5 Not fast! 
5 Not fast! 
5.5 Not fast! 
6 Not fast! 
6.5 Not fast! 
7 Not fast! 
7.5 Not fast! 
8 Not fast! 
8.5 Not fast! 
9 Not fast! 
9.5 Not fast! 
10 That's slooooow 
10.5 That's slooooow