2011-07-08 10 views
8

Estoy teniendo algunos problemas para entender por qué el siguiente no da lugar a un error de compilación en 5.3.3 (con error de salida correctamente en mis compañeros de trabajo 5.2.5):PHP permitiendo que el código no válido en sentencias switch

<?php 
    echo "starting\n"; 

    switch(1) { 
     case 2: 
      echo "two\n"; 
      break; 
     defalut:  // note the misspelling 
      echo "deflaut\n"; 
    } 

    echo "ending\n"; 

en vez de darme un error del compilador (o incluso una advertencia) que sólo da esto:

starting 
ending 

Sin embargo, si lo uso en una sentencia if me da lo que cabe esperar:

<?php 
    if (1 == deflaut) 
     echo "deflaut2\n"; 

da:

PHP Notice: Use of undefined constant deflaut - assumed 'deflaut' in ... 

¿Por qué es esto? ¿Existe un entorno en el que pueda desactivarlo para decirle que sea estricto sobre este tipo de cosas?

+0

Una gran pregunta. Me inclino a pensar que es un error en 5.3.3 pero estoy interesado en ver cuáles son las respuestas. – Endophage

+2

Sin mencionar el hecho de que muchas personas están leyendo el código pero no la pregunta :-P – Endophage

+0

@Ben: Esa no es la pregunta. – hakre

Respuesta

4

El problema es que su código no está haciendo lo que usted piensa. Un bloque case solo finaliza cuando se produce el siguiente bloque case, o cuando se encuentra default:, o cuando se alcanza el } de cierre. Esto significa que defalut es parte del bloque case 2:. Entonces nunca es interpretado.

Sin embargo, ni siquiera disparar un error de sintaxis (ni siquiera si lo hace switch (2). Esto se debe a que el operador goto fue introducido en PHP 5.3. La sintaxis word: al comienzo de una declaración PHP es ahora accesible un objetivo a través de goto. Así goto defalut; se puede utilizar para ir a la etiqueta.

(en realidad, no puede, debido a una restricción de objetivos en el interior switch bloques para evitar bucles infinitos, pero esto debería ilustrar el punto ...)

Puedes hacerlo forzar un error o haciendo case defalut, cuando se encuentre el error esperado.

+0

Gran explicación que tiene mucho sentido. +1 y gracias. – Endophage

+0

"Esto se debe a que el operador goto se introdujo en PHP 5.3". ಠ_ಠ –

8

Posiblemente podría ser interpretándola como otra etiqueta (lo cual tiene sentido, dado que técnicamente es default una etiqueta y case podría interpretarse como un tipo especial de etiqueta también) que podría ser utilizado con goto. Pruebe goto y descubra. Lo haría, pero no tengo PHP 5.3.3, lo siento.

+0

Esto es correcto. Existen problemas similares en C/C++ http://bytes.com/topic/c/answers/217909-faulty-default – Rodaine

+0

Entonces, ¿por qué habría error en 5.2? ¿Qué versión de PHP debería considerarse la que no lo maneja correctamente? ¿O es esto un cambio intencional? – Endophage

+0

@Endophage: No lo sé. – Ryan

1

Interesante, en mi 5.3.2, esto falla SI no hay ninguna otra declaración de caso sobre el valor predeterminado incorrecto.

Esta muere con un error de sintaxis "T_UNEXPECTED_STRING": trabaja

switch (1) { 
    defalut: 
     echo "this should never come out"; 
     break; 
    default: 
     echo "default matched properly" 
} 

Ésta:

switch (1) { 
    case 2: 
     echo "2\n"; 
     break; 
    defalut: 
     echo "this should never come out"; 
     break; 
    default: 
     echo "the default value\n"; 
} 

Parecería que ha encontrado un error en el intérprete de PHP. No consideraría un error grave, pero un error, no obstante.

+1

Esto se debe a que todo el código en una construcción de interruptor debe aparecer dentro de un 'caso' o 'predeterminado'. Recibiría un * nada inesperado * si no está dentro de un 'caso' o 'predeterminado'. Su segundo ejemplo es una etiqueta dentro de un 'caso' por lo que se compila. – webbiedave

+0

Técnicamente, el caso debe considerarse cerrado por la declaración de interrupción. Pero supongo que si el árbol de análisis de PHP solo se cierra en otro caso o en un valor por defecto real, esto tendría sentido. –

Cuestiones relacionadas