2008-08-21 8 views
5

He oído rumores de que PHP está planeando introducir un comando "goto". ¿Qué se supone que debe estar haciendo?GOTO comando en PHP?

He intentado buscar un poco, pero no he encontrado nada terriblemente descriptivo. Entiendo que no será un comando similar al "GOTO 10" ...

+1

Y de hecho lo es en PHP5. Y lo que hace es, "simplemente ir". –

Respuesta

9

No agregan un GOTO real, pero extienden la palabra clave BREAK para usar etiquetas estáticas. Básicamente, mejorará la capacidad de romper switch anidado si las declaraciones. Aquí está el ejemplo concepto que encontré:

<?php 
for ($i = 0; $i < 9; $i++) { 
    if (true) { 
     break blah; 
    } 
    echo "not shown"; 
    blah: 
    echo "iteration $i\n"; 
} 
?> 

Por supuesto, una vez que el GOTO "rumor" estaba fuera, no había nada para detener a algunos chicos malos para propagar una comefrom broma adicional. Esté alerta.

Consulte también:

http://www.php.net/~derick/meeting-notes.html#adding-goto

+4

Creo que es realmente confuso, porque una ruptura por sí misma saltará del bucle for, no solo la declaración if. – DisgruntledGoat

3

De acuerdo, no soy un programador de PHP, y no sé cómo se verá la implementación exacta de PHP de GOTO, pero aquí está mi comprensión de GOTO:

GOTO es simplemente una declaración de control de flujo más explícita como cualquier otra. Digamos que tienes algunos bucles anidados y solo necesitas encontrar una cosa. Puede poner en una declaración condicional (o varias) y cuando las condiciones se cumplen adecuadamente, puede usar una instrucción GOTO para salir de todos los bucles (en lugar de tener una instrucción 'break' en cada nivel de anidación con una instrucción condicional . para cada y sí, creo que la aplicación tradicional es tener etiquetas con nombre que la sentencia GOTO puede saltar a por su nombre Usted puede hacer algo como esto:.

for(...) { 
    for (...) { 
     for (...) { 
     // some code 
     if (x) GOTO outside; 
     } 
    } 
} 
:outside 

esta es una implementación más simple (y más eficiente) . que sin GOTO el equivalente sería:

for(...) { 
    for (...) { 
     for (...) { 
      // some code 
      if (x) break; 
     } 
     if(x) break; 
    } 
    if(x) break; 
} 

En el segundo caso (que es una práctica común) hay thre e declaraciones condicionales, que obviamente son más lentas que solo tener una. Por lo tanto, por motivos de optimización/simplificación, es posible que desee utilizar las sentencias GOTO en bucles estrechamente anidados.

+0

No necesita GOTO por este motivo. Vea mi respuesta para una forma más estructurada de expresar la ruptura de bucles que siempre funciona e introduce cero ineficacia. Goto para este propósito es simplemente tonto. (No es un reflejo de ti.) –

0

Es looks como está actualmente en PHP 5.3, pero aún no está completamente documentado. Por lo que puedo decir, comparte su sintaxis goto con C, por lo que debería ser fácil de usar y recoger. Solo recuerde el warning de Dijkstra y úselo solo cuando sea necesario.

0

@ steveth45

Mi regla de oro es que si ha anidado código de más de 3 niveles de profundidad, que está haciendo algo mal .

Entonces usted no tiene que preocuparse de usar múltiples sentencias break o Ir a: D

+0

Estoy un poco de acuerdo, pero a veces los niveles múltiples de bucles anidados son inevitables y no deben ser objeto de burla. – Christian

0

En el ejemplo dado por steveth45 se puede utilizar una función en lugar:

function findItem(...) { 
    for (...) { 
    for (...) { 
     for (...) { 
     if (x) { 
      return theItem; 
     } 
     } 
    } 
    } 
} 

// no need for label now 
theItem = findItem(a, b, c); 
5

Siempre estoy asombrado en lo increíblemente tontos que son los diseñadores de PHP. Si el propósito de utilizar GOTOs es hacer salir de bucles anidados muchas veces más eficientes que hay una manera mejor: los bloques de código marcados y romper las declaraciones que pueden hacer referencia a las etiquetas:

a: for (...) { 
    b: for (...) { 
     c: for (...) { 
       ... 
       break a; 
      } 
     } 
    } 

Ahora es está claro cuál de bucle/bloquear para salir, y la salida está estructurada; no se puede obtener el código de spaghetti con esto como se puede con verdaderos gotos.

Esta es una idea vieja, vieja y vieja. El diseño de buenas estructuras de control de flujo de control se ha resuelto desde los años 70, y la literatura sobre todo esto hace tiempo que se redactó. El teorema de Bohm-Jacopini mostró que se podía codificar cualquier cosa con llamadas a funciones, if-then-else y while while. En la práctica, para romper bloques profundamente anidados, la codificación Bohm-Jacopini estilo requería indicadores booleanos adicionales ("establecer este indicador para salir del ciclo") que era torpemente codificado e ineficiente (no desea tales flags en su bucle interno). Con if-then-else, varios bucles (while, for) y bloque break-to-labeled, puede codificar cualquier algoritmo sin pérdida de eficiencia en . ¿Por qué la gente no lee la literatura, en su lugar de copiar lo que hizo C? Grrr.

+0

¿No es este _break-to-labeled-block_ cosa que mencionó exactamente lo que se está presentando con esta nueva característica de PHP? Perdóname si me equivoco –

+0

¿Qué característica nueva? ¿IR? GOTO lo llevará a una etiqueta colocada en alguna parte aleatoria de su código. El break-to-label * only * permite roturas desde el interior de un bloque hasta la salida del bloque. –

+0

Bueno, supongo que esa cosa _break-to-label_ que mencionaste es ** exactamente ** lo que se rumorea que se introdujo en php6. No está reviviendo GOTO. –