Ist es möglich, Ausnahmen abzufangen und die Ausführung des Skripts fortzusetzen?
73
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.
pass
in Python?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 abera()
eine Ausnahme ausgelöst,b()
wird diese nicht ausgeführt.Legen Sie das Zeug nur in den
try
Block, der voneinander abhängig ist. ZBb
hängt von einem Ergebnis ab,a
es macht keinen Sinn,b
nach demtry-catch
Block zu setzen .quelle
$e
muss\Exception $e
oder ähnlich sein oder ein Analysefehler wird ausgelöstcatch
. Andernfalls bricht der Code nur und es ist möglicherweise schwer zu erkennen, warum.Sicher:
try { throw new Exception('Something bad'); } catch (Exception $e) { // Do nothing }
Vielleicht möchten Sie die PHP-Dokumentation zu Ausnahmen lesen .
quelle
catch
Block abgefangen wird , kann dies niemals zu einer nicht erfassten Ausnahme führen.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:
quelle
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.
quelle
Throwable
besser alsException
?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.
quelle
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.
quelle