Ich habe try..catch-Blöcke in meinem PHP-Code verwendet, bin mir aber nicht sicher, ob ich sie richtig verwendet habe.
Zum Beispiel sieht ein Teil meines Codes so aus:
try {
$tableAresults = $dbHandler->doSomethingWithTableA();
$tableBresults = $dbHandler->doSomethingElseWithTableB();
} catch (Exception $e) {
return $e;
}
Ich gruppiere also mehrere Datenbankoperationen in demselben Try / Catch-Block, da ich in der Lage sein werde, eine Ausnahme zu behandeln, wenn in einer der Transaktionen eine Ausnahme auftritt.
Ich mache das so, weil ich denke, dass es lesbarer und effizienter ist als:
try {
$tableAresults = $dbHandler->doSomethingWithTableA();
} catch (Exception $e) {
return $e;
}
try {
$tableBresults = $dbHandler->doSomethingWithTableB();
} catch (Exception $e) {
return $e;
}
Ich bin mir jedoch nicht sicher, ob das, was ich tue, eine gute Praxis oder nur ein fauler Weg ist, Ausnahmen zu fangen.
Ich gehe davon aus, dass eine Ausnahme, die eine spezielle Behandlung erfordert, einen eigenen try / catch-Block haben sollte, andernfalls sollte es in Ordnung sein, sie im selben try / catch zu gruppieren.
Meine Frage (n) sind also:
Gibt es einen Vorteil bei der Verwendung von Try / Catch-Blöcken pro Datenbanktransaktion? oder kann ich trotzdem problemlos mehrere Datenbanktransaktionen im selben Try / Catch-Block gruppieren?
Ist es in Ordnung, Try / Catch-Blöcke zu verschachteln? Vielen Dank!
BEARBEITEN
Die return-Anweisung diente hauptsächlich zu Demonstrationszwecken, aber ich verwende auch return-in, catch()
da ich eine AJAX-Anforderung an diese Methode stelle und Javascript ein JSON-Objekt erwartet. Wenn eine Ausnahme auftritt, gebe ich ein leeres JSON-codiertes Array zurück . Ich dachte nur, dass es keinen Wert hinzufügen würde, bestimmten Code in mein Beispiel einzufügen.
quelle
FOREIGN KEYS
beteiligt? Hängen Transaktionen in Tabelle B von denen in Tabelle A ab? Das ist es, was Sie sich fragen müssen, um zu entscheiden, ob Sie sie gruppieren können oder nicht.try{}
Block. Diejenigen, die ich mache ... fahren nach demcatch(){}
Ende fort.Antworten:
Wichtige Notiz
In der folgenden Diskussion wird davon ausgegangen, dass es sich um Code handelt, der wie im obigen Beispiel strukturiert ist: Unabhängig davon, welche Alternative ausgewählt wird, führt eine Ausnahme dazu, dass die Methode logischerweise aufhört, das zu tun, was sie gerade war.
Solange Sie beabsichtigen, dasselbe zu tun, unabhängig davon, welche Anweisung im
try
Block eine Ausnahme auslöst, ist es sicherlich besser, ein einzelnestry
/ zu verwendencatch
. Zum Beispiel:function createCar() { try { install_engine(); install_brakes(); } catch (Exception $e) { die("I could not create a car"); } }
Mehrere
try
/catch
Blöcke sind nützlich, wenn Sie den Fehler auf eine Weise behandeln können und beabsichtigen, die genau darauf zurückzuführen ist, was ihn genau verursacht hat.function makeCocktail() { try { pour_ingredients(); stir(); } catch (Exception $e) { die("I could not make you a cocktail"); } try { put_decorative_umbrella(); } catch (Exception $e) { echo "We 're out of umbrellas, but the drink itself is fine" } }
quelle
finally
Aus Gründen der Nachwelt ist die Antwort möglicherweise zu spät. Sie sollten nach dem Rückgabewert der Variablen suchen und eine Ausnahme auslösen. In diesem Fall können Sie sicher sein, dass das Programm von der Stelle, an der die Ausnahme ausgelöst wird, zum catch-Block springt. Finden Sie unten.
try{ $tableAresults = $dbHandler->doSomethingWithTableA(); if (!tableAresults) throw new Exception('Problem with tableAresults'); $tableBresults = $dbHandler->doSomethingElseWithTableB(); if (!tableBresults) throw new Exception('Problem with tableBresults'); } catch (Exception $e) { echo $e->getMessage(); }
quelle
Es ist besser lesbar, einen einzelnen Versuch Catch Block. Wenn es wichtig ist, eine Art Fehler zu identifizieren, empfehle ich, Ihre Ausnahmen anzupassen.
try { $tableAresults = $dbHandler->doSomethingWithTableA(); $tableBresults = $dbHandler->doSomethingElseWithTableB(); } catch (TableAException $e){ throw $e; } catch (Exception $e) { throw $e; }
quelle
Es gibt keinen Grund gegen die Verwendung eines einzelnen Blocks für mehrere Operationen, da jede ausgelöste Ausnahme die Ausführung weiterer Operationen nach der fehlgeschlagenen verhindert. Zumindest solange Sie aus der abgefangenen Ausnahme schließen können, welcher Vorgang fehlgeschlagen ist. Das ist so lange es in Ordnung ist, wenn einige Operationen nicht verarbeitet werden.
Ich würde jedoch sagen, dass die Rückgabe der Ausnahme nur begrenzt sinnvoll ist. Ein Rückgabewert einer Funktion sollte das erwartete Ergebnis einer Aktion sein, nicht die Ausnahme. Wenn Sie auf die Ausnahme im aufrufenden Bereich reagieren müssen, fangen Sie die Ausnahme entweder nicht hier in Ihrer Funktion, sondern im aufrufenden Bereich ab oder lösen Sie die Ausnahme zur späteren Verarbeitung erneut aus, nachdem Sie einige Debug-Protokollierungen und dergleichen durchgeführt haben.
quelle
Wenn eine Ausnahme ausgelöst wird, wird die Ausführung sofort angehalten und am
catch{}
Block fortgesetzt . Dies bedeutet, dass es nicht auftritt , wenn Sie die Datenbankaufrufe im selbentry{}
Block platzieren und$tableAresults = $dbHandler->doSomethingWithTableA();
eine Ausnahme$tableBresults = $dbHandler->doSomethingElseWithTableB();
auslösen. Bei Ihrer zweiten Option tritt dies$tableBresults = $dbHandler->doSomethingElseWithTableB();
weiterhin auf, da nach demcatch{}
Block die Ausführung wieder aufgenommen wurde.Es gibt keine ideale Option für jede Situation; Wenn Sie möchten, dass der zweite Vorgang unabhängig davon fortgesetzt wird, müssen Sie zwei Blöcke verwenden. Wenn es akzeptabel (oder wünschenswert) ist, dass die zweite Operation nicht ausgeführt wird, sollten Sie nur eine verwenden.
quelle
In einem einzigen Versuch-Catch-Block können Sie alles tun. Die beste Vorgehensweise besteht darin, den Fehler in einem anderen Catch-Block abzufangen, wenn Sie möchten, dass sie für bestimmte Fehler mit ihrer eigenen Nachricht angezeigt werden.
quelle
try { $tableAresults = $dbHandler->doSomethingWithTableA(); if(!tableAresults) { throw new Exception('Problem with tableAresults'); } $tableBresults = $dbHandler->doSomethingElseWithTableB(); if(!tableBresults) { throw new Exception('Problem with tableBresults'); } } catch (Exception $e) { echo $e->getMessage(); }
quelle
Es ist kein Problem, mehrere Ausführungszeilen mit einem einzigen try catch-Block wie unten zu schreiben
try{ install_engine(); install_break(); } catch(Exception $e){ show_exception($e->getMessage()); }
In dem Moment, in dem eine Ausführung entweder in
install_engine
oder in derinstall_break
Funktion erfolgt, wird die Steuerung an die Catch-Funktion übergeben. Eine weitere Empfehlung ist, Ihre Ausnahme richtig zu essen. Das heißt, anstatt zu schreibendie('Message')
, ist es immer ratsam, den Ausnahmevorgang ordnungsgemäß durchzuführen. Möglicherweise möchten Sie diedie()
Funktion bei der Fehlerbehandlung verwenden, nicht jedoch bei der Ausnahmebehandlung.Wenn Sie einen Catch-Block mit mehreren Versuchen verwenden sollten Sie können sich einen Catch-Block mit mehreren Versuchen vorstellen, wenn die Ausnahme des unterschiedlichen Codeblocks unterschiedliche Ausnahmetypen anzeigen soll oder wenn Sie versuchen, eine Ausnahme aus Ihrem Catch-Block wie folgt auszulösen:
try{ install_engine(); install_break(); } catch(Exception $e){ show_exception($e->getMessage()); } try{ install_body(); paint_body(); install_interiour(); } catch(Exception $e){ throw new exception('Body Makeover faield') }
quelle