Ich möchte einen saubereren Weg, um die folgenden Funktionen zu erhalten, zu fangen AError
und BError
in einem Block:
try
{
/* something */
}
catch( AError, BError $e )
{
handler1( $e )
}
catch( Exception $e )
{
handler2( $e )
}
Gibt es eine Möglichkeit, dies zu tun? Oder muss ich sie separat fangen?
AError
und Berror
haben eine gemeinsame Basisklasse, aber sie teilen sie auch mit anderen Typen, zu denen ich gerne durchfallen würde handler2
, sodass ich die Basisklasse nicht einfach abfangen kann.
php
exception-handling
Dominic Gurto
quelle
quelle
Antworten:
Aktualisieren:
Ab PHP 7.1 ist dies verfügbar.
Die Syntax lautet:
Dokumente: https://www.php.net/manual/en/language.exceptions.php#example-287
RFC: https://wiki.php.net/rfc/multiple-catch
Festschreiben: https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a
Für PHP vor 7.1:
Ungeachtet dessen, was diese anderen Antworten sagen, können Sie
AError
undBError
im selben Block fangen (es ist etwas einfacher, wenn Sie derjenige sind, der die Ausnahmen definiert). Selbst wenn es Ausnahmen gibt, durch die Sie "fallen" möchten, sollten Sie dennoch in der Lage sein, eine Hierarchie zu definieren, die Ihren Anforderungen entspricht.Dann:
Wie Sie hier und hier sehen können , haben selbst die
SPL
Standardausnahmen eine Hierarchie, die Sie nutzen können. Zusätzlich, wie im PHP-Handbuch angegeben :Das heißt, Sie könnten auch haben
die Sie anders als
AError
oder behandeln müssenBError
, damit Ihre catch-Anweisung folgendermaßen aussehen würde:Wenn Sie den Fall hatten, dass es zwanzig oder mehr Ausnahmen gab, die rechtmäßig zu derselben Oberklasse gehörten, und Sie fünf (oder eine große Gruppe) davon auf die eine und den Rest auf die andere Weise behandeln mussten, können Sie dies NOCH tun.
Und dann:
Die Verwendung von OOP bei Ausnahmen ist sehr leistungsfähig. Die Verwendung von Dingen wie
get_class
oderinstanceof
sind Hacks und sollte nach Möglichkeit vermieden werden.Eine andere Lösung, die ich hinzufügen möchte, besteht darin, die Ausnahmebehandlungsfunktion in eine eigene Methode zu integrieren.
Du könntest haben
Unter der Annahme , es gibt absolut keine Möglichkeit, Ausnahmeklassenhierarchien oder Schnittstellen steuern kann (und fast immer wird ein Weg sein), können Sie Folgendes tun:
Auf diese Weise haben Sie immer noch einen einzigen Code-Speicherort, den Sie ändern müssen, wenn sich Ihr Ausnahmebehandlungsmechanismus ändern muss, und Sie arbeiten innerhalb der allgemeinen Konstrukte von OOP.
quelle
AError
könnte in einer Bibliothek / Datei implementiert werden, die von einem Dritten aktualisiert wird.In PHP> = 7.1 ist dies möglich. Siehe die Antwort unten.
Wenn Sie die Ausnahmen ändern können, verwenden Sie diese Antwort .
Wenn Sie nicht können, können Sie versuchen, alle mit zu fangen
Exception
und dann zu überprüfen, mit welcher Ausnahme ausgelöst wurdeinstanceof
.Aber es wäre wahrscheinlich besser, mehrere Fangblöcke zu verwenden, wie in der oben genannten Antwort beschrieben .
quelle
finally
Aussage kümmern . ;)... } else { throw($e); }
wenn es nicht zu den beiden passt. Entschuldigung für die möglicherweise falsche Syntax, habe PHP eine Weile nicht gesehen.Kommt in PHP 7.1 mehrere Typen abgefangen werden.
Damit das:
und
sind funktional gleichwertig.
quelle
Ab PHP 7.1,
Interessanterweise können Sie auch:
und in früheren Versionen von PHP:
quelle
Dieser Artikel behandelt die Frage elektrictoolbox.com/php-catch-multiple-exception-types . Inhalt des Beitrags direkt aus dem Artikel kopiert:
Beispiel Ausnahmen
Hier sind einige Beispielausnahmen, die für die Zwecke dieses Beispiels definiert wurden:
Behandlung mehrerer Ausnahmen
Es ist sehr einfach - es kann einen Fangblock für jeden Ausnahmetyp geben, der ausgelöst werden kann:
Wenn eine Ausnahme ausgelöst wird, die von keiner der anderen catch-Anweisungen behandelt wird, wird sie vom catch-Block (Exception $ e) behandelt. Es muss nicht unbedingt der letzte sein.
quelle
catch (Throwable $e)
alle Ausnahmen abfangen. Siehe auch: php.net/manual/en/class.throwable.phpAls Erweiterung der akzeptierten Antwort können Sie den Ausnahmetyp ändern, was zu einem Muster führt, das dem ursprünglichen Beispiel ähnelt:
quelle
Hier ist eine sinnvolle Alternative, wenn Sie keine Kontrolle über die Definition der Ausnahmen haben. Verwenden Sie den Namen der Ausnahmevariablen, um die Ausnahmen zu kategorisieren, wenn sie abgefangen werden. Suchen Sie dann nach dem try / catch-Block nach der Ausnahmevariablen.
Dieser etwas seltsam aussehende Ansatz lohnt sich wahrscheinlich nur, wenn zwischen den Catch-Block-Implementierungen viele Überschneidungen bestehen.
quelle
Neben dem Fall-Through ist es auch möglich, mit goto überzugehen . Es ist sehr nützlich, wenn Sie die Welt brennen sehen möchten.
3v4l.org
quelle
Ein guter Weg ist zu verwenden
set_exception_handler
.Warnung!!! Mit PHP 7 wird möglicherweise ein weißer Todesbildschirm für schwerwiegende Fehler angezeigt. Wenn Sie beispielsweise eine Methode für ein Nicht-Objekt aufrufen, erhalten Sie diese normalerweise
Fatal error: Call to a member function your_method() on null
und Sie würden dies erwarten, wenn die Fehlerberichterstattung aktiviert ist.Der obige Fehler wird NICHT abgefangen
catch(Exception $e)
. Der obige Fehler löst KEINEN benutzerdefinierten Fehlerbehandler aus, der von festgelegt wurdeset_error_handler
.Sie müssen verwenden
catch(Error $e){ }
, um Fehler in PHP7 abzufangen. . Dies könnte helfen:quelle
catch (Throwable $e) { ... }
und damit fertig sein. Siehe auch: php.net/manual/en/class.throwable.phpEine andere Option, die hier nicht aufgeführt ist, besteht darin, das
code
Attribut einer Ausnahme zu verwenden, sodass Sie Folgendes tun können:quelle
extends \Exception
?Hmm, es gibt viele Lösungen für PHP-Versionen unter 7.1.
Hier ist eine andere einfache für diejenigen, die nicht alle Ausnahmen abfangen möchten und keine gemeinsamen Schnittstellen erstellen können:
quelle