Gibt es eine Möglichkeit, die if-Anweisung in PHP zu brechen?

128

Gibt es in PHP einen Befehl, die Ausführung der aktuellen oder übergeordneten ifAnweisung zu beenden , genau wie breakoder break(1)für switch/loop . Beispielsweise

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

echo "finish";

im obigen Code reicht PHP nicht aus echo "test"; und geht zuecho "finish";

Ich brauche das für wenn

$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";

Ich möchte breakdie ifobige Anweisung befolgen und die Ausführung beendenecho "yes"; oder solche Codes, die nicht mehr ausgeführt werden müssen, möglicherweise eine zusätzliche Bedingung haben oder nicht. Gibt es eine Möglichkeit, dies zu tun?

Update: Nur 2 Jahre nach dem Posten dieser Frage bin ich aufgewachsen und habe gelernt, wie Code in kleinen Stücken geschrieben werden kann, warum verschachtelte Ifs nach Code riechen können und wie man solche Probleme überhaupt vermeidet, indem man überschaubare, kleine Funktionen schreibt.

Muhammad Usman
quelle
14
Keines Ihrer Beispiele macht logisch Sinn.
Tim Pietzcker
1
@Usman: Wenn es keine Bedingung gibt, wird die echo(in Ihrem Beispiel) niemals ausgeführt. Sie können es also genauso gut löschen.
Oliver Charlesworth
2
Ist das keine try catchOption?
Giannis Christofakis
Zuerst dachte ich, Tim sei einfach unhöflich ... Aber dann dachte ich, er hat Recht ... Warum sollten Sie einen Code hinter einer bedingungslosen Pause haben? Debuggen? Ich mag es, mit continue für Schleifen auszubrechen; Und es wäre schön, sehr schwierige Abfragen mit einem Befehl "einfach hier anhalten" aufzubrechen ...if (condition) { if ( oneothercondition ) stop; if ( yetothercondition ) stop; // go ahead , all is fine }
Joeri
@Joeri Ich kenne Muhhamads anfängliche Ideen nicht, warum er eine Pause brauchte. Aber in meinem Fall handelt es sich jetzt um Debugging-Zwecke, richtig. In einigen Fällen würde dies Zeit sparen. In Fällen, in denen keine Haltepunkte hinzugefügt werden können (wenn Sie keine IDE verwenden und / oder aus bestimmten Gründen an einer Live-Site arbeiten müssen usw.)
Viktor Borítás

Antworten:

216

Machen Sie sich keine Sorgen über Kommentare anderer Benutzer, ich kann Sie verstehen, MANCHMAL, wenn Sie diese "ausgefallenen" Dinge entwickeln, sind sie erforderlich . Wenn wir ein Wenn brechen können, sind viele verschachtelte Wenns nicht erforderlich, was den Code viel sauberer und ästhetischer macht.

Dieser Beispielcode veranschaulicht, dass BESTIMMTE SITUATIONEN, bei denen ein Fehler aufgetreten ist, viel besser geeignet sind als viele hässliche verschachtelte Ifs. Wenn Sie dieser bestimmten Situation nicht begegnet sind, bedeutet dies nicht, dass sie nicht vorhanden ist .

Hässlicher 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();

}

Gut aussehender Code

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

Wie @NiematojakTomasz sagt, ist die Verwendung von gotoeine Alternative. Das Schlechte daran ist, dass Sie immer die Bezeichnung (Punktziel) definieren müssen.

AgelessEssence
quelle
29
Toll! Manchmal werden Fragen aufgrund ihres tiefen Sinnes missverstanden. Du hast es perfekt verstanden, ich brauche sauberen Code, um das Ende vonif
Muhammad Usman,
4
Ich musste nach jedem erfolgreichen Test (ungefähr 3 oder 4 Tests) den gleichen Code ausführen und elseifbei jedem fehlgeschlagenen Test einen Code setzen . Genau das habe ich gesucht, jetzt ist mein Code KISS- und DRY-konform :) Danke!
s3v3n
3
Mann das fühlt sich dreckig an! Aber es bekommt meine Gegenstimme. Ich arbeite an einem schmutzigen System;)
LeonardChallis
8
@rdlowrey, das Gespräch ist kostenlos, also zeigen Sie uns bitte ein Beispiel für "Gut geschriebenes OOP", um die OP-Frage zu lösen: 3
AgelessEssence
7
Verwechseln Sie die Anfrage von sample nicht mit persönlichen Angriffen ... in der Tat fehlt Ihnen etwas Wichtiges, nicht jede Codierung sollte OOP sein, ist eine verrückte Sache, einfache Aufgaben mit der Magie * von OOP zu schreiben.
AgelessEssence
97

Kapseln Sie Ihren Code in eine Funktion. Sie können die Ausführung einer Funktion returnjederzeit mit beenden .

Maxim Krizhanovsky
quelle
2
Ich dachte du wolltest ein Wenn, keine Funktion? ;)
Arnaud Le Blanc
3
@ arnaud576875 Wenn sich der Code in einer Funktion befindet, können Sie return in der if-Anweisung verwenden, um die Ausführung zu unterbrechen.
Maxim Krizhanovsky
1
Eine Funktion sollte "1 Weg rein" und "1 Weg raus" haben. Multiple RETURNS ist schlampig und fehleranfällig.
Alter Mann Walter
@OldManWalter Dies gilt nur für die Rückgabe tatsächlicher Daten. Die Fehlerbehandlung ist jedoch eine häufige Ausnahme von dieser Regel. Eine Wurfausnahme oder die Rückgabe von false an mehreren Orten sind durchaus akzeptabel, ohne die üblichen Fallstricke zu treffen, vor denen die Mentalität "1 Weg rein, 1 Weg raus" zu schützen versucht.
Danielson317
41

richtige Art und Weise, dies zu tun:

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

Nachdem ich einige der Kommentare gelesen hatte, stellte ich fest, dass die Ausnahmebehandlung für eine normale Flusskontrolle nicht immer sinnvoll ist. Für einen normalen Kontrollfluss ist es besser, "If else" zu verwenden:

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

Sie können die Prozessrückgabewerte auch in Variablen speichern und dann in den Fehler- / Ausnahmeblöcken überprüfen, welcher Prozess fehlgeschlagen ist.

Rahul Ranjan
quelle
1
Ausnahmen können in diesen Fällen nützlich sein, aber es scheint, dass Sie sie missbrauchen. Ausnahmen sind außergewöhnlich, nicht für den normalen Programmablauf. Wenn der Fehler außergewöhnlich ist, sollte process_x-z die Ausnahme selbst auslösen. clean_all_processes () wäre in einem finally-Block besser, da es sich um eine Bereinigung handelt, die ohnehin durchgeführt werden muss.
Jimmy T.
Ich habe die Lösung verbessert.
Rahul Ranjan
Grund, warum ich es nicht endlich benutzt habe, ist, dass es erst ab php5.5 unterstützt wird
Rahul Ranjan
20

Da Sie aus einer do / while-Schleife ausbrechen können , lassen Sie uns eine Runde " machen ". Mit einer Weile (falsch) am Ende ist die Bedingung nie wahr und wird sich nicht wiederholen.

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
quelle
Niemand sagt, dass Sie das verwenden müssen. Es ist nur ein Beispiel, um "auszubrechen".
Markus Zeller
2
Ordentlicher Ansatz - erledigt den Job.
Benjamin
16

gehe zu :

Mit dem goto- Operator können Sie zu einem anderen Abschnitt im Programm springen. Der Zielpunkt wird durch eine Beschriftung gefolgt von einem Doppelpunkt angegeben, und die Anweisung wird als goto gefolgt von der gewünschten Zielbeschriftung angegeben. Dies ist kein uneingeschränkter Goto . Die Zielbezeichnung muss sich in derselben Datei und demselben Kontext befinden. Dies bedeutet, dass Sie weder aus einer Funktion oder Methode herausspringen noch in eine springen können. Sie können auch nicht in eine Schleifen- oder Schalterstruktur springen. Sie können aus diesen herausspringen, und eine übliche Verwendung ist die Verwendung eines goto anstelle einer mehrstufigen Pause ...

NiematojakTomasz
quelle
82
Jedes Mal goto, wenn Sie es benutzen , frisst das Jesuskind ein Kätzchen. Auch xkcd.com/292
12
Tut mir leid, dass ich konsequent bin. Ich habe auf die PHP-Handbuchseite verwiesen, auf der die genaue Verwendung des genannten Schlüsselworts erläutert wird. Und selbst wenn es eine schmutzige Lösung ist, ist es immer noch die richtige Lösung.
NiematojakTomasz
3
Ich verstehe nicht genau, warum es keine gute Praxis ist, dies zu tun? Es ist viel einfacher als alle anderen Lösungen?
538ROMEO
1
Einverstanden mit Sébastien. In einigen Fällen ist der goto-Operator sehr nützlich und einfach.
Jerry
6
Keine Sorge, Programmierer geben Ihnen immer das Gefühl, dass Sie nicht richtig codieren, und möchten, dass wir wie sie codieren. Dies gilt umso mehr für die PHP-Community, da wir eine Gruppe von Hipster-Programmierern sind und PHP uns diese Freiheitsschlüsselwörter und die Freiheit gibt, so wertend darüber zu sein, wie jeder Dinge tut. Ich habe das gotoSchlüsselwort (nicht ausgiebig) in Produktionscodes verwendet und hatte nie Probleme.
Vdegenne
7

Es gibt Befehl: goto

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


}



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

Denken Sie jedoch daran, dass dies gotokeine empfohlene Vorgehensweise ist, da der Code dadurch ungewöhnlich formatiert wird.

T.Todua
quelle
1
Ich habe dieses Skript getestet, der folgende Code geht zu Area1; wird nicht ausgeführt.
Leon Armstrong
5

Nein, es gibt keine Möglichkeit, einen if-Block so zu "brechen", wie Sie es in Schleifen tun würden. :(
Machen Sie aus Ihrem Test einen switch!

Ich frage mich, warum Sie seitdem niemand mehr dazu ermutigt hat, die switch-Anweisung zu verwenden (auch wenn Sie nicht zu viele Testfälle haben).
Denken Sie, dass sie zu ausführlich ist?

Ich würde es auf jeden Fall hier versuchen

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

Für mich sollen Ausnahmen Fehler auslösen und Ausführungsfehler nicht wirklich kontrollieren.
Wenn es sich bei dem Unterbrechungsverhalten, das Sie festlegen möchten, nicht um unerwartete Fehler handelt, ist die Ausnahmebehandlung hier nicht die richtige Lösung :/.

Stphane
quelle
Interessante Idee, aber ich würde sie nicht für "echten" Code verwenden.
Jimmy T.
1
"echt", was meinst du? :/
Stphane
1
@Stphane Ein später Kommentar, aber die Verwendung eines Schalters in dieser Situation widerspricht dem Prinzip des geringsten Erstaunens. Es wird erwartet, dass eine switch-Anweisung die Auswahl von Daten steuert und nicht den Programmfluss.
FWDekker
« Switch vergleicht einen Ausdruck mit unterschiedlichen Werten und führt einen bestimmten Codeblock aus, je nachdem, welchem ​​Wert der Ausdruck entspricht.» Dann kann jeder Block untergeordnete Ausdrücke auswerten, die wiederum den Ausführungsablauf anweisen, einige Anweisungen zurückzugeben oder zu überspringen. Ich glaube nicht, dass der Wechsel in diesem sehr engen Anwendungsfall gegen das Prinzip des geringsten Erstaunens verstoßen würde, aber dies sagte, den ursprünglichen Kontext und Anforderungen können in der Tat einige Refactoring erfordern.
Stphane
4
$a = 1;

switch($a) {

  case "1":

    if  ($condition1){
      break;
    }

    if  ($condition2){
      break;
    }

    if  ($condition3){
      break;
    }
}

Auf diese Weise habe ich bekommen, was ich will. Ich benutze einen Schalter hat nur einen bestimmten Fall und benutze dann break in case, um zu wählen, ob Bedingung. Der Grund, warum ich die Pause verwende: Bedingung1 und Bedingung2 können beide erfüllen, in dieser Situation wird nur Bedingung1 angewendet .IF ist gemäß der Reihenfolge selektiv.

user3530437
quelle
8
Sie brauchen dafür keine Variable. Verwenden Sie einfachswitch(true) { case true:
Maxim Krizhanovsky
1

Nein.

Aber wie wäre es mit:

$a="test";
if("test"==$a)
{
  if ($someOtherCondition)
  {
    echo "yes";
  }
}
echo "finish";
Oliver Charlesworth
quelle
3
Danke, aber ich suche nach einer einfacheren Version, um zu viele ifAussagen zu vermeiden
Muhammad Usman
2
@Usman: Wenn Sie mehrere Bedingungen haben, müssen Sie diese überprüfen. Das Überprüfen einer Bedingung beinhaltet traditionell eine ifAussage. Ich bin mir nicht sicher, wie Sie dies vermeiden sollen.
Oliver Charlesworth
1

Verschieben Sie einfach den Code, der nicht ausgeführt werden soll, in den else/elseifZweig. Ich verstehe nicht wirklich, warum Sie das tun wollen, was Sie versuchen.

Mchl
quelle
1

Die einfache Antwort lautet: Nein, es gibt keine Möglichkeit, von einer ifAnweisung abzubrechen , ohne die Ausführung vollständig zu stoppen (via exit). Andere Lösungen funktionieren bei mir nicht if, da ich die Struktur der Anweisung nicht ändern kann , da ich Code wie folgt in ein Plugin einfüge:

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
quelle
0

Wenn Sie auf Ihre Frage antworten, ob dies erreichbar ist oder nicht, dann ist dies mit dem "goto" -Operator von php erreichbar.

Aber ethisch gesehen ist es keine gute Praxis, "goto" zu verwenden, und wenn goto verwendet werden muss, bedeutet dies, dass der Code so rekonstruiert werden muss, dass die Anforderung von goto entfernt werden kann.

Anhand des oben veröffentlichten Beispielcodes ist deutlich zu erkennen, dass der Code rekonstruiert werden kann und der nicht mehr benötigte Code entweder gelöscht oder kommentiert werden kann (sofern die Möglichkeit einer zukünftigen Verwendung besteht).

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

Wenn Sie Ihre Aussagen kombinieren, würde dies Ihnen das gewünschte Ergebnis bringen. sauber und einfach, ohne zu viele Aussagen zu haben.

Für den hässlichen und gut aussehenden Code wäre meine Empfehlung:

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

irgendwo in Ihrem normalen Code

myfunction();
Arthur Kielbasa
quelle
0

Ich denke du suchst das:

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

    // go ahead , all is fine
}

Das PHP-Handbuch zeigt forBeispiele, aber ich denke, es funktioniert auch fürif

Joeri
quelle
-1

Ich habe eine einfache Lösung ohne viele Änderungen. Die erste Aussage ist

Ich möchte die obige if-Anweisung brechen und die Ausführung des Echos "yes" beenden. oder solche Codes, die nicht mehr ausgeführt werden müssen, es kann eine zusätzliche Bedingung geben oder nicht, gibt es eine Möglichkeit, dies zu tun?

so scheint es einfach. Versuchen Sie Code wie diesen.

$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";

Wenn Sie es ohne diesen Code versuchen möchten, ist es einfach. und Sie können zurück, wenn Sie wollen. Eine andere Lösung sind Kommentarblöcke. oder denken Sie einfach nach und versuchen Sie es mit einem anderen getrennten Code und kopieren Sie nur das Ergebnis in Ihren endgültigen Code. und wenn ein Code in Ihrem Fall nicht mehr erforderlich ist, kann das Ergebnis sein

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

Mit diesem Code wird die ursprüngliche Aussage vollständig respektiert .. :) und besser lesbar!

Christian Audebert
quelle
-2

Die einfache Lösung besteht darin, es auskommentieren.

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

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

Der zusätzliche Vorteil besteht darin, dass Sie Ihren ursprünglichen Code nicht ändern und ihn datieren, initialisieren und einen Grund dafür angeben können.

Warum die Abstimmung nach unten, laut OP-Anfrage halte ich dies für eine absolut gültige Lösung.

"Ich möchte [die obige if-Anweisung brechen und] die Ausführung des Echos" yes "beenden. Oder solche Codes, die nicht mehr ausgeführt werden müssen, können eine zusätzliche Bedingung sein oder nicht. Gibt es eine Möglichkeit, dies zu tun?"

Tatsächlich könnte sich jemand ein Jahr später einige der anderen Lösungen ansehen und sich fragen, was dort vor sich geht. Nach meinem Vorschlag könnte man eine gute Dokumentation zum späteren Nachschlagen hinterlassen, was immer eine gute Praxis ist.

ArtisticPhoenix
quelle
2
Dies löst das Problem nicht. Die Pause könnte auch in einem Wenn sein.
Jimmy T.
Sie können eine if-Anweisung nicht kommentieren? Oder einen auskommentieren? Meinen Sie ein if, um die Ausführung auszuschließen? Wenn ja, wozu dient dann die Pause? Ist das nicht was, wenn Aussagen dafür sind? Kommentieren Sie das einfach auch aus. Entschuldigung, aber verstehe deinen Standpunkt nicht.
ArtisticPhoenix
So etwas wie das: a: if ("test" == $ a) {... if (...) break a; ...}
Jimmy T.
-3

Was ist mit der Verwendung eines ternären Operators?

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

Welches ist identisch mit dieser if / else-Anweisung:

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

Um den Rest des Skripts vollständig zu stoppen, können Sie dies einfach tun

Ausfahrt; // Anstelle von Pause. Der Rest des Codes wird nicht ausgeführt

Mark Kasina
quelle
-4

Ich bin zu spät zur Party, aber ich wollte dazu beitragen. Ich bin überrascht, dass niemand vorgeschlagen hat exit(). Es ist gut zum Testen. Ich benutze es die ganze Zeit und arbeitet wie Charme.

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

Der Code stoppt bei exit()und alles danach wird nicht ausgeführt.

Ergebnis

Clark Kent is Superman

Es funktioniert mit foreach()und while()auch. Es funktioniert überall dort, wo Sie es wirklich platzieren.

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

echo "finish";

Ergebnis

nothing gets printed here.

Verwenden Sie es mit einem forloop()

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

Ergebnis

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

Im Normalfall

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

Ergebnis

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