¿Alguna forma de romper si la declaración en PHP?

129

¿Hay algún comando en PHP para detener la ejecución de la ifdeclaración actual o principal , igual breako break(1)para switch/ loop? Por ejemplo

$arr=array('a','b');
foreach($arr as $val)
{
  break;
  echo "test";
}

echo "finish";

en el código anterior PHP no lo hará echo "test";e irá aecho "finish";

Necesito esto para si

$a="test";
if("test"==$a)
{
  break;
  echo "yes"; // I don't want this line or lines after to be executed, without using another if
}
echo "finish";

Quiero breakla ifdeclaración anterior y dejar de ejecutar echo "yes";o los códigos que ya no son necesarios para ejecutar, puede haber o no una condición adicional, ¿hay alguna manera de hacerlo?

Actualización: solo 2 años después de publicar esta pregunta, crecí, aprendí cómo se puede escribir el código en pequeños fragmentos, por qué anidar si puede ser un olor a código y cómo evitar tales problemas en primer lugar escribiendo funciones manejables y pequeñas.

Muhammad Usman
fuente
15
Ninguno de sus ejemplos tiene sentido lógicamente.
Tim Pietzcker
1
@Usman: si no hay una condición, entonces echo(en su ejemplo) nunca se ejecutará. Así que también podrías eliminarlo.
Oliver Charlesworth
2
¿No es try catchuna opción?
giannis christofakis
Primero pensé que Tim era grosero ... Pero luego pensé que estaba en lo correcto ... ¿Por qué tendrías algún código detrás de un corte incondicional? Depuración? Me gusta salir de bucles con continuar; Y sería bueno romper las consultas muy difíciles con un comando "solo para aquí" ...if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
Joeri
@Joeri, no sé las ideas iniciales de Muhhamad por qué necesitaba un descanso; Pero en mi caso ahora son propósitos de depuración, correcto. En algunos casos, ahorraría tiempo. En los casos en que no pueda agregar puntos de interrupción '(cuando no use un IDE y / o tenga que trabajar en un sitio en vivo por alguna razón, etc.)
Viktor Borítás

Respuestas:

216

No se preocupe por los comentarios de otros usuarios, puedo entenderlo, A VECES al desarrollar estas cosas "sofisticadas" son necesarias . Si podemos romper un if, no serán necesarios muchos ifs anidados, haciendo que el código sea mucho más limpio y estético.

Este código de ejemplo ilustra que CIERTAS SITUACIONES en las que se viola pueden ser mucho más adecuadas que muchos ifs feos y anidados ... si no ha enfrentado esa situación determinada no significa que no exista .

Código feo

if(process_x()) {

    /* do a lot of other things */

    if(process_y()) {

         /* do a lot of other things */

         if(process_z()) {

              /* do a lot of other things */
              /* SUCCESS */

         }
         else {

              clean_all_processes();

         }

    }
    else {

         clean_all_processes();

    }

}
else {

    clean_all_processes();

}

Código de buena apariencia

do {

  if( !process_x() )
    { clean_all_processes();  break; }

  /* do a lot of other things */

  if( !process_y() )
    { clean_all_processes();  break; }

  /* do a lot of other things */

  if( !process_z() )
    { clean_all_processes();  break; }

  /* do a lot of other things */
  /* SUCCESS */

} while (0);

Como dice @NiematojakTomasz, el uso de gotoes una alternativa, lo malo de esto es que siempre debe definir la etiqueta (objetivo de punto).

Esencia sin edad
fuente
29
¡Excelente! A veces las preguntas se malinterpretan debido a su profundo sentido. Ya lo tienes perfectamente, necesito un código limpio para que no entre el final deif
Muhammad Usman
44
Necesitaba ejecutar el mismo código después de cada prueba exitosa (alrededor de 3 o 4 pruebas), y poner una elseifen cada prueba fallida. Esto es exactamente lo que estaba buscando, ahora mi código es compatible con KISS y DRY :) ¡Gracias!
s3v3n
3
¡Hombre, esto se siente sucio! Pero recibe mi voto positivo ... Estoy trabajando en un sistema sucio;)
LeonardChallis
8
@rdlowrey, hablar es gratis, así que POR FAVOR muéstranos un ejemplo de "POO bien escrito" para resolver la pregunta de OP: 3
AgelessEssence
77
No confunda la solicitud de la muestra con los ataques personales ... de hecho, se está perdiendo algo importante, no toda la codificación debe ser OOP, es una locura escribir tareas simples con la magia * de OOP.
AgelessEssence
98

Encapsula tu código en una función. Puede dejar de ejecutar una función returnen cualquier momento.

Maxim Krizhanovsky
fuente
2
¿Pensé que querías un if, no una función? ;)
Arnaud Le Blanc
3
@ arnaud576875 si el código está en una función, puede usar return en la instrucción if para interrumpir la ejecución.
Maxim Krizhanovsky
1
Una función debe tener "1 entrada" y "1 salida". Múltiples DEVOLUCIONES es descuidado y propenso a errores.
Viejo Walter
@OldManWalter Eso solo es cierto para devolver datos reales. Sin embargo, el manejo de errores es una excepción común a esta regla. Una excepción de lanzamiento o un retorno falso en múltiples ubicaciones son perfectamente aceptables sin llegar a las trampas comunes contra las cuales la mentalidad de "1 entrada, 1 salida" está tratando de proteger.
danielson317
41

forma correcta de hacer esto:

try{
    if( !process_x() ){
        throw new Exception('process_x failed');
    }

    /* do a lot of other things */

    if( !process_y() ){
        throw new Exception('process_y failed');
    }

    /* do a lot of other things */

    if( !process_z() ){
        throw new Exception('process_z failed');
    }

    /* do a lot of other things */
    /* SUCCESS */
}catch(Exception $ex){
    clean_all_processes();
}

Después de leer algunos de los comentarios, me di cuenta de que el manejo de excepciones no siempre tiene sentido para el control de flujo normal. Para un flujo de control normal, es mejor usar "If else":

try{
  if( process_x() && process_y() && process_z() ) {
    // all processes successful
    // do something
  } else {
    //one of the processes failed
    clean_all_processes();
  }
}catch(Exception ex){
  // one of the processes raised an exception
  clean_all_processes();
}

También puede guardar los valores de retorno del proceso en variables y luego verificar en los bloques de falla / excepción qué proceso ha fallado.

Rahul Ranjan
fuente
1
Las excepciones pueden ser útiles en estos casos, pero parece que las usa incorrectamente. Las excepciones son excepcionales, no para el flujo normal del programa. Si el fallo es excepcional, entonces process_x-z debería arrojar la excepción por sí mismo; clean_all_processes () sería mejor en un bloque final ya que es una limpieza que debe hacerse de todos modos.
Jimmy T.
He mejorado la solución.
Rahul Ranjan
La razón que no usé finalmente es que no es compatible hasta php5.5
Rahul Ranjan
20

Porque se puede romper de un do / while, vamos a " hacer " una ronda. Con un tiempo (falso) al final, la condición nunca es verdadera y no se repetirá nuevamente.

do
{
    $subjectText = trim(filter_input(INPUT_POST, 'subject'));
    if(!$subjectText)
    {
        $smallInfo = 'Please give a subject.';
        break;
    }

    $messageText = trim(filter_input(INPUT_POST, 'message'));
    if(!$messageText)
    {
        $smallInfo = 'Please supply a message.';
        break;
    }
} while(false);
Markus Zeller
fuente
Nadie dice que debes usar eso. Es solo un ejemplo para "romper".
Markus Zeller
2
Enfoque ordenado: hace el trabajo.
benjaminhull
16

ir a :

El operador goto se puede usar para saltar a otra sección del programa. El punto objetivo se especifica mediante una etiqueta seguida de dos puntos, y la instrucción se da como goto seguida de la etiqueta objetivo deseada. Este no es un goto completo sin restricciones . La etiqueta de destino debe estar dentro del mismo archivo y contexto, lo que significa que no puede saltar de una función o método, ni puede saltar a uno. Tampoco puede saltar a ningún tipo de estructura de bucle o conmutador. Puede saltar de estos, y un uso común es usar un goto en lugar de un descanso de varios niveles ...

NiematojakTomasz
fuente
82
Cada vez que usa goto, el Niño Jesús se come un gatito. Además, xkcd.com/292
12
Perdón por ser consistente. He hecho referencia a la página del manual de php que explica el uso exacto de la palabra clave mencionada. E incluso si es una solución sucia, sigue siendo la solución correcta.
NiematojakTomasz
3
No entiendo exactamente cómo no es una buena práctica hacerlo. ¿Es mucho más simple que todas las demás soluciones?
538ROMEO
1
De acuerdo con Sébastien. En algunos casos, el operador goto es muy útil y simple.
Jerry
66
No se preocupe, los programadores siempre le harán sentir que no está codificando correctamente y que quieren que codifiquemos como ellos. Esto es aún más cierto en la comunidad php porque somos un grupo de codificadores hipster y PHP nos da estas palabras clave de libertad y la libertad de ser tan críticos con respecto a cómo todos hacen las cosas. He usado (no ampliamente) la gotopalabra clave en los códigos de producción y nunca he tenido problemas.
vdegenne
7

Existe un comando: goto

if(smth) {
   .....
   .....
   .....
   .....
   .....
   goto Area1;
   .....
   .....


}



Area1:
....your code here....

Sin embargo, recordar gotono es una práctica recomendada, porque hace que el código se formatee de forma inusual.

T.Todua
fuente
1
He probado este script, el código debajo de goto Area1; No se ejecutará.
Leon Armstrong el
5

No, no hay forma de "romper" un bloque if como lo haría dentro de los bucles. :(
¡Así que convierte tu prueba en una switch!

Me pregunto por qué nadie lo alentó a usar la declaración de cambio ya que (incluso si no tiene muchos casos de prueba)
¿Cree que es demasiado detallado?

Definitivamente lo haría aquí

  switch($a){
    case 'test':
        # do stuff here ...
        if(/* Reason why you may break */){
           break; # this will prevent executing "echo 'yes';" statement
        }
        echo 'yes';  # ...           
        break; # As one may already know, we might always have to break at the end of case to prevent executing following cases instructions.
    # default:
        # something else here  ..
        # break;
  }

Para mí, las excepciones están destinadas a generar errores y no a controlar realmente la falla de ejecución.
Si el comportamiento de interrupción que está intentando establecer no se trata de errores inesperados, el manejo de excepciones no es la solución correcta aquí :/.

Stphane
fuente
Idea interesante pero no la usaría para código "real".
Jimmy T.
1
"real", ¿qué quieres decir? :/
Stphane
1
@Stphane Un comentario tardío, pero usar un interruptor en esta situación va en contra del principio del mínimo asombro. Se espera que una declaración de cambio controle la selección de datos, no el flujo del programa.
FWDekker
« Switch compara una expresión con diferentes valores y ejecuta un bloque de código específico en función de a qué valor equivale la expresión». Luego, cada bloque puede evaluar expresiones subsidiarias que a su vez pueden indicar al flujo de ejecución que regrese u omitir algunas instrucciones ... No creo que el cambio vaya en contra del principio de menor asombro en este caso de uso muy limitado, pero dicho esto, el contexto original y los requisitos pueden requerir cierta refactorización.
Stphane
4
$a = 1;

switch($a) {

  case "1":

    if  ($condition1){
      break;
    }

    if  ($condition2){
      break;
    }

    if  ($condition3){
      break;
    }
}

De esta manera obtuve lo que quiero. Utilizo un interruptor solo tiene un caso definido y luego uso break in case para elegir si condición. La razón por la que uso el corte: la condición1 y la condición2 pueden satisfacer, en esa situación solo se aplica la condición1 .IF es selectivo según el orden.

usuario3530437
fuente
8
No necesitas variable para esto. Solo useswitch(true) { case true:
Maxim Krizhanovsky
1

No.

Pero que tal:

$a="test";
if("test"==$a)
{
  if ($someOtherCondition)
  {
    echo "yes";
  }
}
echo "finish";
Oliver Charlesworth
fuente
3
Gracias, pero estoy buscando una versión más simple para evitar demasiadas ifdeclaraciones
Muhammad Usman
2
@Usman: si tiene varias condiciones, debe verificarlas. Verificar una condición tradicionalmente implica una ifdeclaración. No estoy seguro de cómo esperas evitar esto.
Oliver Charlesworth
1

Simplemente mueva el código que no debe ejecutarse a la else/elseifbifurcación. Realmente no veo por qué querrías hacer lo que estás tratando de hacer.

Mchl
fuente
1

La respuesta simple es que no, no hay una manera de romper una ifdeclaración sin detener completamente la ejecución (vía exit). Otras soluciones no funcionarán para mí porque no puedo cambiar la estructura de la ifdeclaración, ya que estoy inyectando código en un complemento, así:

if ( condition ) {
  // Code and variables I want to use

  // Code I have control over

  // Code I don't want to run
}
// More code I want to use
David
fuente
0

Respondiendo a su pregunta si eso se puede lograr o no, entonces sí, eso se puede lograr utilizando el operador "goto" de php.

Pero éticamente, no es una buena práctica usar "goto" y si hay alguna necesidad de usar goto, entonces esto significa que el código debe reconstruirse de tal manera que se pueda eliminar el requisito de goto.

De acuerdo con el código de muestra que publicó anteriormente, se puede ver claramente que el código se puede reconstruir y el código que ya no es necesario se puede eliminar o comentar (si existe la posibilidad de usarlo en el futuro).

Sandeep Garg
fuente
0
$arr=array('test','go for it');
$a='test';
foreach($arr as $val){
  $output = 'test';
  if($val === $a) $output = "";
  echo $output;
}
echo "finish";

combinando sus declaraciones, creo que esto le daría el resultado deseado. limpio y simple, sin tener demasiadas declaraciones.

para el código feo y atractivo, mi recomendación sería:

function myfunction(){
  if( !process_x() || !process_y() || !process_z()) {
    clean_all_processes();  
    return; 
  }
/*do all the stuff you need to do*/
}

en algún lugar de tu código normal

myfunction();
Arthur Kielbasa
fuente
0

Creo que estás buscando esto:

if (condition) { 
    if ( oneothercondition ) continue;  
    if ( yetothercondition ) continue; 

    // go ahead , all is fine
}

El manual de php muestra forejemplos, pero creo que también funciona paraif

Joeri
fuente
-1

Tengo una solución simple sin muchos cambios. la declaración inicial es

Quiero romper la declaración if anterior y dejar de ejecutar echo "yes"; o tales códigos que ya no son necesarios para ser ejecutados, puede haber o no una condición adicional, ¿hay alguna manera de hacerlo?

Entonces, parece simple. prueba un código como este.

$a="test";
if("test"==$a)
{
  if (1==0){
      echo "yes"; // this line while never be executed. 
      // and can be reexecuted simply by changing if (1==0) to if (1==1) 
  }
}
echo "finish";

si quieres probar sin este código, es simple. y puedes retroceder cuando quieras. Otra solución son los bloques de comentarios. o simplemente pensando e intente con otro código separado y copie y pegue solo el resultado en su código final. y si un código ya no es necesario, en su caso, el resultado puede ser

$a="test";
echo "finish";

con este código, la declaración original se respeta por completo ... :) y es más legible.

Christian Audebert
fuente
-2

La solución simple es comentarlo.

$a="test";
if("test"==$a)
{

  //echo "yes"; //no longer needed - 7/7/2014 - updateded bla bla to do foo
}

El beneficio adicional es que no está cambiando su código original y puede fecharlo, inicializarlo y explicar el motivo.

Por qué el voto negativo, de acuerdo con la solicitud de OP, creo que esta es una solución perfectamente válida.

"Quiero [romper la declaración if anterior y] dejar de ejecutar echo" yes "; o tales códigos que ya no son necesarios para ejecutar, puede haber o no una condición adicional, ¿hay alguna forma de hacerlo?"

De hecho, alguien podría mirar algunas de las otras soluciones, un año más tarde y preguntarse qué está pasando allí. Según mi sugerencia, uno podría dejar buena documentación para referencia futura, que siempre es una buena práctica.

Fénix Artístico
fuente
2
Esto no resuelve el problema. El descanso también podría ser en un if.
Jimmy T.
¿No puedes comentar en una declaración if? O comentar uno? ¿Te refieres a usar un if para excluir la ejecución? Si es así, ¿cuál es el punto de la ruptura entonces, no es eso para qué sirven las declaraciones? Solo comente eso también. Lo siento, pero no veo tu punto.
ArtisticPhoenix
Algo como esto: a: if ("test" == $ a) {... if (...) break a; ...}
Jimmy T.
-3

¿Qué pasa con el uso del operador ternario?

<?php
 // Example usage for: Ternary Operator
 $action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
?>

Que es idéntico a esta declaración if / else:

<?php
 if (empty($_POST['action'])) {
   $action = 'default';
 } else {
   $action = $_POST['action'];
 }
?>
Martin Stone
fuente
En PHP7:$a = $_POST['action'] ?? 'default';
Tobias Mühl el
-3

Para detener por completo la ejecución del resto del script, simplemente puede hacer

salida; // En lugar de descanso. El resto del código no se ejecutará

Mark Kasina
fuente
-4

Llego tarde a la fiesta pero quería contribuir. Me sorprende que nadie sugirió exit(). Es bueno para probar. Lo uso todo el tiempo y funciona a las mil maravillas.

$a ='';
$b ='';
if($a == $b){
echo 'Clark Kent is Superman';
exit();
echo 'Clark Kent was never Superman';
}

El código se detendrá exit()y todo lo demás no se ejecutará.

Resultado

Clark Kent is Superman

Funciona con foreach()y while()también. Funciona en cualquier lugar donde lo coloques realmente.

foreach($arr as $val)
{
  exit();
  echo "test";
}

echo "finish";

Resultado

nothing gets printed here.

Úselo con un forloop()

for ($x = 2; $x < 12; $x++) {
    echo "Gru has $x minions <br>";
    if($x == 4){
    exit();
    }
}

Resultado

Gru has 2 minions
Gru has 3 minions
Gru has 4 minions

En un caso normal

$a ='Make hot chocolate great again!';
echo $a;
exit();
$b = 'I eat chocolate and make Charlie at the Factory pay for it.';

Resultado

Make hot chocolate great again!
Lucha globo
fuente
-7
$a="test";
if("test"!=$a)
{
echo "yes";                   
}
 else
 {
  echo "finish";
}
Shanon
fuente