php: Ausnahme abfangen und Ausführung fortsetzen, ist das möglich?

73

Ist es möglich, Ausnahmen abzufangen und die Ausführung des Skripts fortzusetzen?

Kirzilla
quelle

Antworten:

101

Sicher, fangen Sie einfach die Ausnahme, wo Sie die Ausführung fortsetzen möchten ...

  try
  {
      SomeOperation();
  }
  catch (SomeException $e)
  {
      // do nothing... php will ignore and continue    
  }

Dies hat natürlich das Problem, einen möglicherweise sehr wichtigen Fehler stillschweigend fallen zu lassen. SomeOperation () kann fehlschlagen und andere subtile, schwer herauszufindende Probleme verursachen, aber Sie würden nie erfahren, ob Sie die Ausnahme stillschweigend löschen.

Doug T.
quelle
7
Wenn ich hinzufügen möchte: Das Abfangen einer Ausnahme, ohne etwas im catch-Block zu tun, wird als schlechter Stil angesehen. Sie sollten zumindest eine Protokollausgabe schreiben (oder, wie im Beispiel, einen Kommentar abgeben, dass wirklich, wirklich, wirklich nichts getan werden muss ). Dies gilt insbesondere dann, wenn Sie eine Ausnahme mit catch (Exception $ ex) {}
Morfildur
2
Wie protokollierst du es und machst trotzdem weiter?
numerisch25
2
Die beste Übung ist zu verwenden: Try -> Catch (Ausnahme behandeln) -> Schließlich (wo schließlich immer läuft) bin ich vielleicht falsch mit deinen Gedanken, aber ich wollte dir trotzdem etwas Input geben.
Bram B
Gibt es eine eingebaute Methode (oder Konvention), um explizit "nichts tun" zu sagen, wie z. B. passin Python?
cprn
Wichtig: Wenn Sie in Ihren Code eine Zeile einfügen: [Bedingung oder sterben ("was auch immer")] funktioniert der Try-Catch nicht, töten Sie das Programm sofort. Es hat Logik ... nachdem Sie den Code debuggt
Grenville Tryon
133

Ja, aber es hängt davon ab, was Sie ausführen möchten:

Z.B

try {
   a();
   b();
}
catch(Exception $e){
}

c();

c()wird immer ausgeführt. Wird aber a()eine Ausnahme ausgelöst, b()wird diese nicht ausgeführt.

Legen Sie das Zeug nur in den tryBlock, der voneinander abhängig ist. ZB bhängt von einem Ergebnis ab, aes macht keinen Sinn, bnach dem try-catchBlock zu setzen .

Felix Kling
quelle
Ich habe in Ihrem Namen getan :)
Christian M. Raymonds
2
$emuss \Exception $eoder ähnlich sein oder ein Analysefehler wird ausgelöst
iautomation
Das war eine großartige Erklärung
Thejas
Einfache Erklärung. Es sollte noch einmal betont werden, dass es wichtig ist, in den meisten Fällen etwas Sinnvolles innerhalb der zu tun catch. Andernfalls bricht der Code nur und es ist möglicherweise schwer zu erkennen, warum.
MQuiggGeorgia
c () wird ausgeführt, wenn es jetzt einen Wurf innerhalb des
Fangblocks
16

Sicher:

try {
   throw new Exception('Something bad');
} catch (Exception $e) {
    // Do nothing
}

Vielleicht möchten Sie die PHP-Dokumentation zu Ausnahmen lesen .

Dominic Rodger
quelle
Dies wird eine neue Ausnahme auslösen, die jetzt vom Try-Block abgefangen wird. Dies führt zu einer nicht erfassten Ausnahme
Jake N
1
@ JakeN nicht wahr. Da die ausgelöste Ausnahme vom catchBlock abgefangen wird , kann dies niemals zu einer nicht erfassten Ausnahme führen.
Pere
2
Ich habe jetzt meinen Kommentar gelesen. Und ich habe buchstäblich keine Ahnung, was ich meinte!
Jake N
@JakeN Ein try- Block kann keine Ausnahme abfangen .
Ejaz
6

Ja.

try {
    Somecode();
catch (Exception $e) {
    // handle or ignore exception here. 
}

Beachten Sie jedoch, dass PHP auch Fehlercodes enthält, die von Ausnahmen getrennt sind. Dies ist ein Überbleibsel aus früheren Zeiten, als PHP keine Grundelemente hatte. Die meisten integrierten Bibliotheken lösen immer noch Fehlercodes aus, keine Ausnahmen. Um einen Fehlercode zu ignorieren, rufen Sie die Funktion mit dem Präfix @ auf:

@myfunction();
Crast
quelle
5

PHP> 7

Verwenden Sie die neue Schnittstelle Throwable

    try {
        // Code that may throw an Exception or Error.
    } catch (Throwable $t) {
        // Handle exception
    }

echo "Script is still running..."; // this script will be executed.
Abdessamad
quelle
1
Wenn Sie jemandem sagen, er solle etwas "benutzen", sagen Sie auch "warum". Warum ist Throwablebesser als Exception?
Daniel W.
0

Ein weiterer Aspekt ist die Rückgabe einer Ausnahme, die KEINE auslöst, aus dem Verarbeitungscode.

Ich musste dies mit einem Vorlagen-Framework tun, das ich schreibe. Wenn der Benutzer versucht , eine Eigenschaft zuzugreifen , die nicht auf den Daten vorhanden ist , ich zurückgeben die Fehler aus den Tiefen der Verarbeitungsfunktion, anstatt sie zu werfen.

Dann kann ich im aufrufenden Code entscheiden, ob dieser zurückgegebene Fehler ausgelöst werden soll, wodurch try () abgefangen wird (), oder einfach fortfahren:

// process the template
    try
    {
        // this function will pass back a value, or a TemplateExecption if invalid
            $result = $this->process($value);

        // if the result is an error, choose what to do with it
            if($result instanceof TemplateExecption)
            {
                if(DEBUGGING == TRUE)
                {
                    throw($result); // throw the original error
                }
                else
                {
                    $result = NULL; // ignore the error
                }
            }
    }

// catch TemplateExceptions
    catch(TemplateException $e)
    {
        // handle template exceptions
    }

// catch normal PHP Exceptions
    catch(Exception $e)
    {
        // handle normal exceptions
    }

// if we get here, $result was valid, or ignored
    return $result;

Das Ergebnis ist, dass ich immer noch den Kontext des ursprünglichen Fehlers erhalte, obwohl er oben geworfen wurde.

Eine andere Möglichkeit könnte darin bestehen, ein benutzerdefiniertes NullObject- oder ein UnknownProperty-Objekt zurückzugeben und mit diesem zu vergleichen, bevor Sie sich entscheiden, den catch () auszulösen. Da Sie jedoch trotzdem Fehler erneut auslösen können und die vollständige Kontrolle über die Gesamtstruktur haben, I. Ich denke, dies ist ein guter Weg, um das Problem zu umgehen, dass Versuche / Fänge nicht fortgesetzt werden können.

davestewart
quelle
0

Eine alte Frage, aber eine, die ich in der Vergangenheit hatte, als ich von VBA-Skripten zu PHP kam, wo Sie uns "GoTo" geben konnten, um eine Schleife "On Error" mit einem "Resume" erneut einzugeben, und die Funktion wurde weiterhin verarbeitet .
In PHP verwende ich nach einigem Ausprobieren jetzt den verschachtelten Versuch {} catch {} für kritische oder nicht kritische Prozesse oder sogar für voneinander abhängige Klassenaufrufe, damit ich meinen Weg zurück zum Anfang des Fehlers verfolgen kann. zB wenn Funktion b von Funktion a abhängig ist, aber Funktion c schön zu haben ist, aber den Prozess nicht stoppen sollte, und ich trotzdem die Ergebnisse aller 3 wissen möchte, unabhängig davon, was ich tue:

//set up array to capture output of all 3 functions
$resultArr = array(array(), array(), array());

// Loop through the primary array and run the functions 
foreach($x as $key => $val)
{
    try
    {
        $resultArr[$key][0][] = a($key); 
        $resultArr[$key][1][] = b($val);
        try
        { // If successful, output of c() is captured
            $resultArr[$key][2][] = c($key, $val);
        }
        catch(Exception $ex)
        { // If an error, capture why c() failed
            $resultArr[$key][2][] = $ex->getMessage();
        }
    }
    catch(Exception $ex)
    { // If critical functions a() or b() fail, we catch the reason why
        $criticalError = $ex->getMessage();
    }
} 

Jetzt kann ich mein Ergebnisarray für jeden Schlüssel durchlaufen und die Ergebnisse bewerten. Wenn ein kritischer Fehler für a () oder b () vorliegt.
Ich habe immer noch einen Bezugspunkt, wie weit es gekommen ist, bevor ein kritischer Fehler im $ resultArr aufgetreten ist, und wenn der Ausnahmebehandler richtig eingestellt ist, weiß ich, ob a () oder b () fehlgeschlagen sind.
Wenn c () fehlschlägt, läuft die Schleife weiter. Wenn c () an verschiedenen Stellen fehlgeschlagen ist, kann ich mit ein wenig zusätzlicher Post-Loop-Logik sogar herausfinden, ob c () bei jeder Iteration funktioniert hat oder einen Fehler hatte, indem ich $ resultArr [$ key] [2] abfrage.

Roy
quelle