2010-08-19 14 views
57

¿Hay alguna forma de hacerlo para que el siguiente código todavía use un interruptor y devuelva b no a? ¡Gracias!hacer uso del interruptor === comparación no == comparación En PHP

$var = 0; 
switch($var) { 
    case NULL : return 'a'; break; 
    default : return 'b'; break; 
} 

Usando si las declaraciones, por supuesto, que lo harían así:

$var = 0; 
if($var === NULL) return 'a'; 
else return 'b'; 

embargo, para ejemplos más complejos, esto se convierte en verbosa.

Respuesta

40

En este momento, no se puede utilizar una comparación === en una sentencia switch, ya que según el switch() documentation:

Tenga en cuenta que el interruptor/caja hace la comparación suelta.

Esto significa que tendrá que encontrar una solución. De the loose comparisons table, usted podría hacer uso del hecho de que NULL == "0" es falso según el tipo de calidad:

<?php 
$var = 0; 
switch((string)$var) 
{ 
    case "" : echo 'a'; break; // This tests for NULL or empty string 
    default : echo 'b'; break; // Everything else, including zero 
} 
// Output: 'b' 
?> 

Live Demo

+3

Entonces, ¿cuál es el punto de 'cambiar'? ¿Caer a través? – strager

+0

Bueno, hay otras circunstancias (no solo con NULL) con las que me gustaría que esto funcione. –

+3

¡Esto no funcionará! Esto es equivalente a 'if ($ var == is_null ($ var))' que nunca será verdadero (si '$ var' es' NULL', será 'NULL == true'). –

1

hacer uso del interruptor === == comparación no comparación En PHP

Desafortunadamente switch usa comparación suelta y, que yo sepa, no hay forma de cambiar eso.

1

Nope. Desde manual page:

Tenga en cuenta que el interruptor/caja hace loose comparison.

Si solo tiene dos condiciones, use un if como su segundo ejemplo. De lo contrario, la verificación de NULL primero y encender las otras posibilidades:

if (is_null($var)) 
{ 
    return 'a'; 
} 

switch ($var) 
{ 
    // ... 
} 
0

Esto no es posible.

Puede, sin embargo, poner los if declaraciones dentro la switch:

switch($var) { 
    // Loose cases here 

    case 0: 
     if($var === NULL) { 
      return 'a'; 
     } 

     // Fall through 

    default: 
     return 'b'; 
} 

O simplemente:

switch($var) { 
    // Loose cases here 

    default: 
     if($var === NULL) { 
      return 'a'; 
     } 

     return 'b'; 
} 
+7

En ese momento ¿por qué molestarse con el interruptor? Incluso podría hacer 'cambiar (verdadero) {caso $ var === nulo: ...} – ircmaxell

+0

@ ircmaxell, asumí que el OP quiere una lógica fallida o una razón para usar 'switch' más allá de un estricto control a veces. – strager

54

Una forma de poder hacer esto es hacer lo que consideramos como un interruptor hacia atrás (puede haber un nombre más oficial para él). La idea es que ponga true o false en la parte superior y luego sus condicionales en las declaraciones case.

switch(true) 
{ 
    case ($var === NULL): 
    return 'a'; 
    break; 
    case ($var === 0): 
    return 'b'; 
    break; 
    default: 
    return 'c'; 
} 
+14

¿Cuál es el punto de este frente a solo un bloque if/elseif? –

+3

No tiene sentido hacer esto, y si desea comparar con otros valores, la sintaxis será bastante incómoda. –

+25

Nada más que el estilo de codificación, el resultado final será el mismo. Creo que los interruptores se ven un poco más arreglados si tienes una gran cantidad de condiciones. Prefiero mirar 10 casos que if/elseif/elseif/elseif etc. –

0

También puede cambiar el tipo de la variable:

switch (gettype($var)) { 
... 
} 
+0

Mala idea - De los documentos: 'Nunca use gettype() para probar cierto tipo, ya que la cadena devuelta puede estar sujeta a cambios en una versión futura. Además, es lento también, ya que implica la comparación de cadenas. En su lugar, use las funciones is_ *. –

+0

Si gettype() cambia que haría que la función fuera inútil y el lenguaje menos confiable. El uso de is_ * no responde la pregunta sobre el cambio. Por lo demás, estoy de acuerdo :) – greg

7

No con switch - sólo lo hace comparaciones llama "sueltos". Siempre puede reemplazarlo con un bloque if/else if, usando ===.

+0

¿te refieres a tu experiencia o documentación? Si es el último, publique un enlace – TMS

+0

Ya vinculado :) –

+1

En realidad * puede * hacer esto con 'switch' (vea mi respuesta) aunque creo que' if-else' es mejor para este trabajo en particular. – DaveRandom

2

Presumiblemente está conectando la variable y esperando enteros. ¿Por qué no simplemente verificar el estado entero de la variable de antemano usando is_int($val)?

1

solo utilizo

$var === null and $var = -1; // since switch is not type-safe 
switch ($var) { 
    case 0: 
     # this tests for zero/empty string/false 
     break; 
    case -1: 
     # this tests for null 
     break; 
} 

Creo que esto todavía se ve muy legible si el comentario que comienzan con // se quede atrás (y los iniciados por # son probablemente el mejor suprimido).

0

Uno de la mejor manera es comprobar el valor NULL utilizando is_null

<?php 
echo getValue(); 
function getValue() 
{ 
    $var = 0; 
    switch(true) { 
     case is_null($var) : return 'a'; break; 
     default : return 'b'; break; 
    } 
} 
?> 
+0

Lo mejor, sin embargo, es '=== nulo' ya que evita la sobrecarga de llamada de función innecesaria. – Antti29

2

que tenía el mismo problema en un interruptor con números de cuerda que contiene ("15.2" es igual a "15.20" en un interruptor para php)

me resolvió el problema al añadir una carta antes del texto para comparar

$var = '15.20'; 
switch ('#'.$var) { 
    case '#15.2' : 
     echo 'wrong'; 
    break; 
    case '#15.20' : 
     echo 'right'; 
    break; 
} 
0

Extrapolando a partir de su código de ejemplo, supongo que tienes un montón de cas regulares es y un caso especial (aquí, null).

El más simple que puedo imaginar es para manejar este caso antes del interruptor:

if ($value === null) { 
    return 'null'; 
} 

switch ($value) { 
    case 0: 
     return 'zero'; 
    case 1: 
     return 'one'; 
    case 2: 
     return 'two'; 
} 

Tal vez también añadir un comentario recordar null coincidiría inesperadamente el caso 0 (también el contrario, 0 coincidiría con un null caso).