149 votes

Y a-t-il un moyen de casser l'instruction if en PHP ?

Existe-t-il une commande en PHP permettant d'arrêter l'exécution de la commande courante ou parentale ? if déclaration, comme pour break o break(1) para switch / loop . Par exemple

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

echo "finish";

dans le code ci-dessus, PHP ne fera pas echo "test"; et se rendra à echo "finish";

J'en ai besoin pour 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";

Je veux break le site if ci-dessus et arrêter d'exécuter echo "yes"; ou de tels codes qu'il n'est plus nécessaire d'exécuter, il peut y avoir ou non une condition supplémentaire, y a-t-il un moyen de le faire ?

Mise à jour : Deux ans après avoir posé cette question, j'ai grandi, j'ai appris comment le code peut être écrit en petits morceaux, pourquoi les ifs imbriqués peuvent être une odeur de code et comment éviter de tels problèmes en écrivant de petites fonctions gérables.

1 votes

@Usman : S'il n'y a pas de condition, alors la echo (dans votre exemple) sera jamais être exécuté. Donc vous pourriez aussi bien le supprimer.

2 votes

N'est-ce pas ? try catch une option ?

0 votes

D'abord j'ai pensé que Tim était juste grossier... Mais ensuite j'ai pensé qu'il avait raison... Pourquoi auriez-vous du code derrière une rupture inconditionnelle ? Débogage ? J'aime sortir des boucles for avec continue ; Et ce serait bien d'interrompre des requêtes très difficiles avec une commande "stop ici"... if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }

235voto

iim.hlk Points 1299

Ne vous inquiétez pas des commentaires des autres utilisateurs, je peux vous comprendre, Parfois, lors du développement, des choses "fantaisistes" sont nécessaires. . Si nous pouvons casser un if, beaucoup de ifs imbriqués ne seront pas nécessaires, ce qui rendra le code beaucoup plus propre et esthétique.

Cet exemple de code illustrer qui CERTAINES SITUATIONS où le "breaked if" peut être beaucoup plus approprié qu'un grand nombre d'affreux "ifs" imbriqués... si vous n'avez pas été confronté à cette situation, cela ne signifie pas qu'elle n'existe pas. .

Mauvais code

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();

}

Code de bonne qualité

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);

Comme le dit @NiematojakTomasz, l'utilisation de goto est une alternative, l'inconvénient étant que vous devez toujours définir l'étiquette (point cible).

35 votes

Super ! Parfois, les questions sont mal comprises en raison de leur sens profond. Vous l'avez parfaitement compris, j'ai besoin d'un code propre pour éviter de suivre la fin de if

4 votes

J'avais besoin d'exécuter le même code après chaque test réussi (environ 3 ou 4 tests), et de mettre un fichier de type elseif sur chaque test échoué. C'est exactement ce que je cherchais, maintenant mon code est conforme à KISS et DRY :) Merci !

4 votes

Mec, c'est sale ! Mais il a mon upvote Je travaille sur un système sale ;)

105voto

Darhazer Points 17541

Encapsulez votre code dans une fonction. Vous pouvez arrêter l'exécution d'une fonction avec return à tout moment.

3 votes

Je pensais que vous vouliez un if, pas une fonction ;)

4 votes

@arnaud576875 si le code est dans une fonction, alors vous pouvez utiliser return dans l'instruction if, pour interrompre l'exécution.

1 votes

Une fonction doit avoir "1 voie d'entrée" et "1 voie de sortie". Les RETURNS multiples sont peu soignés et source d'erreurs.

45voto

user3170963 Points 101

La manière correcte de le faire :

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();
}

Après avoir lu certains des commentaires, j'ai réalisé que la gestion des exceptions n'a pas toujours de sens pour le contrôle normal du flux. Pour un flux de contrôle normal, il est préférable d'utiliser "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();
}

Vous pouvez également enregistrer les valeurs de retour des processus dans des variables, puis vérifier dans les blocs d'échec/exception quel processus a échoué.

1 votes

Les exceptions peuvent être utiles dans ce cas, mais il semble que vous les utilisiez mal. Les exceptions sont exceptionnelles, pas pour le déroulement normal du programme. Si l'échec est exceptionnel, alors le process_x-z devrait lancer l'exception par lui-même ; clean_all_processes() serait mieux dans un finally-block puisque c'est un nettoyage qui doit être fait de toute façon.

0 votes

J'ai amélioré la solution.

0 votes

La raison pour laquelle je n'ai pas utilisé finally est qu'il n'est pas supporté jusqu'à php5.5.

17voto

NiematojakTomasz Points 1087

goto :

Le site goto peut être utilisé pour passer à une autre section du programme. Le point cible est spécifié par un label suivi de deux points, et l'instruction est donnée comme suit goto suivi de l'étiquette cible souhaitée. Il ne s'agit pas d'une goto . L'étiquette cible doit se trouver dans le même fichier et dans le même contexte, ce qui signifie que vous ne pouvez pas sauter d'une fonction ou d'une méthode, ni y entrer. Vous ne pouvez pas non plus sauter dans une sorte de boucle ou de structure de commutation. Vous pouvez sauter hors de ces structures, et une utilisation courante est l'utilisation d'une balise goto en lieu et place d'un rupture ...

86 votes

Chaque fois que vous utilisez goto l'enfant Jésus mange un chaton. Et aussi, xkcd.com/292

13 votes

Désolé d'avoir été cohérent. J'ai référencé la page du manuel de php expliquant l'usage exact du mot-clé mentionné. Et même si c'est une solution sale, c'est toujours une solution correcte.

3 votes

Je ne comprends pas exactement en quoi ce n'est pas une bonne pratique de le faire ? C'est beaucoup plus simple que toutes les autres solutions ?

6voto

UltraDEVV Points 117

Vous pourriez utiliser un do-while(false) :

    <?php
    do if ($foo)
    {
      // Do something first...

      // Shall we continue with this block, or exit now?
      if ($abort_if_block) break;

      // Continue doing something...

    } while (false);
    ?>

comme décrit dans http://php.net/manual/en/control-structures.if.php#90073

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X