try
Lernen Sie, wie PHP try/catch/finally Ausnahmen behandelt. Behandelt mehrere catch-Blöcke, Union-Typen, Weiterwerfen und häufige Fallstricke.
Das PHP-Schlüsselwort try
Das Schlüsselwort try markiert einen Codeblock, der eine Exception auslösen könnte — ein Objekt, das signalisiert, dass etwas schiefgelaufen ist und die normale Ausführung nicht fortgesetzt werden kann. Wenn innerhalb eines try-Blocks eine Exception ausgelöst wird, stoppt PHP die Ausführung des restlichen Blocks und sucht nach einem passenden catch-Block, um sie zu behandeln. Ein optionaler finally-Block wird danach ausgeführt, unabhängig davon, was passiert ist.
Diese Seite behandelt die Syntax von try/catch/finally, wie mehrere catch-Blöcke zugeordnet werden, das gleichzeitige Abfangen mehrerer Exception-Typen, das Weiterwerfen und die häufigsten Fallstricke. Wenn Sie neu im Umgang mit dem Auslösen von Fehlern sind, lesen Sie zuerst Exceptions in PHP.
Syntax
try {
// Code that may throw an exception
} catch (ExceptionType $e) {
// Code that runs if an exception of ExceptionType (or a subclass) is thrown
} finally {
// Optional: always runs, whether or not an exception was thrown
}Auf einen try-Block muss mindestens ein catch-Block, ein finally-Block oder beides folgen — ein try allein ist ein Syntaxfehler. Die Variable in catch (ExceptionType $e) enthält das ausgelöste Exception-Objekt, das Sie mit Methoden wie $e->getMessage() abfragen können.
Ein erstes Beispiel
Die folgende Funktion löst eine Exception aus, wenn sie gebeten wird, durch null zu dividieren. Der try-Block ruft sie auf, der catch-Block meldet das Problem, und finally wird immer ausgeführt:
<?php
function divide($dividend, $divisor)
{
if ($divisor == 0) {
throw new Exception("Cannot divide by zero.");
}
return $dividend / $divisor;
}
try {
$result = divide(10, 0);
echo $result; // skipped — divide() threw before returning
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . PHP_EOL;
} finally {
echo "Done." . PHP_EOL;
}Ausgabe:
Error: Cannot divide by zero.
Done.Beachten Sie, dass echo $result; niemals ausgeführt wird: Sobald divide(10, 0) eine Exception auslöst, springt die Kontrolle direkt zum catch-Block. Der finally-Block wird danach ausgeführt. Wenn Sie stattdessen divide(10, 2) aufrufen, wird keine Exception ausgelöst, der try-Block gibt 5 aus, und finally gibt trotzdem Done. aus.
Mehrere catch-Blöcke
Auf ein einzelnes try können mehrere catch-Blöcke folgen. PHP überprüft sie von oben nach unten und führt den ersten aus, dessen Typ mit der ausgelösten Exception übereinstimmt (Übereinstimmung umfasst auch Unterklassen). Listen Sie spezifischere Typen vor allgemeineren auf — ein führendes catch (Exception $e) würde alles darunter verschlucken.
<?php
try {
$value = "5";
if (!is_int($value)) {
throw new TypeError("Expected an integer.");
}
} catch (TypeError $e) {
echo "Type problem: " . $e->getMessage() . PHP_EOL;
} catch (Exception $e) {
echo "Other problem: " . $e->getMessage() . PHP_EOL;
}Ausgabe:
Type problem: Expected an integer.Mehrere Typen in einem Block abfangen
Wenn zwei Exception-Typen auf die gleiche Weise behandelt werden sollen, verbinden Sie sie mit einem senkrechten Strich (|) — eine in PHP 7.1 hinzugefügte Funktion — anstatt den Block zu duplizieren:
<?php
try {
throw new RuntimeException("Network timed out.");
} catch (RuntimeException | LogicException $e) {
echo "Handled: " . $e->getMessage() . PHP_EOL;
}Ausgabe:
Handled: Network timed out.Verhalten von finally
Der finally-Block wird selbst dann ausgeführt, wenn der try- oder catch-Block ein return enthält. Das macht ihn zum richtigen Ort für Bereinigungen — Dateien schließen, Sperren freigeben, eine Transaktion zurückrollen — die auf jedem Ausführungspfad stattfinden müssen:
<?php
function readConfig()
{
try {
return "config loaded";
} finally {
echo "Cleanup ran." . PHP_EOL;
}
}
echo readConfig() . PHP_EOL;Ausgabe:
Cleanup ran.
config loadedDer finally-Block wird vor der tatsächlichen Rückgabe des Funktionswerts ausgeführt. Vermeiden Sie es, aus finally selbst zurückzukehren: Ein return dort überschreibt den Wert aus try/catch und verwirft stillschweigend jede Exception, die gerade ausgelöst wurde.
Eine Exception weiterwerfen
Ein catch-Block kann teilweise Arbeit erledigen — den Fehler protokollieren, Kontext hinzufügen — und dann weiterwerfen, damit ein übergeordneter Aufrufer entscheiden kann, was zu tun ist. Verwenden Sie throw $e;, um dasselbe Objekt weiterzuwerfen:
<?php
try {
try {
throw new Exception("Disk full.");
} catch (Exception $e) {
echo "Logging: " . $e->getMessage() . PHP_EOL;
throw $e; // hand it to the outer handler
}
} catch (Exception $e) {
echo "Outer handler: " . $e->getMessage() . PHP_EOL;
}Ausgabe:
Logging: Disk full.
Outer handler: Disk full.Häufige Fallstricke
trybraucht einen Partner. Eintry-Block allein lässt sich nicht parsen — kombinieren Sie ihn mit mindestens einemcatchoder einemfinally.- Nicht alle Fehler sind Exceptions. Viele Laufzeitwarnungen (eine undefinierte Variable, ein fehlgeschlagenes
fopen()) werden nicht als Exceptions ausgelöst, daher wirdcatchsie nicht sehen. Verwenden Sie für dieseset_error_handler()oder prüfen Sie Rückgabewerte. FataleError-Objekte (wieTypeError) können abgefangen werden, da sieThrowableimplementieren. - Ordnen Sie
catch-Blöcke vom Spezifischen zum Allgemeinen. Ein breitescatch (Exception $e)an erster Stelle verbirgt jeden nachfolgenden Block. - Nicht stillschweigend schlucken. Ein leerer
catch-Block verbirgt den Fehler; protokollieren Sie mindestens$e->getMessage(), damit das Problem sichtbar ist. finallykann Exceptions verbergen. Eine Rückgabe ausfinallyverwirft sowohl dentry-Rückgabewert als auch jede laufende Exception.
Wann sollte ich try verwenden?
Greifen Sie zu try/catch, wenn ein Fehler außergewöhnlich ist und der aufrufende Code vernünftigerweise darauf reagieren kann: eine Datenbankverbindung, die abbricht, eine API, die einen Fehler zurückgibt, ungültige Benutzereingaben, die Sie sauber ablehnen möchten. Für den normalen Kontrollfluss (wurde ein Schlüssel in einem Array gefunden? ist ein string leer?), verwenden Sie normale Bedingungen — Exceptions sind für den abnormalen Pfad, nicht für alltägliche Verzweigungen.
Verwandte Themen
catch— der Block, der eine ausgelöste Exception behandelt.finally— Code, der immer nachtry/catchausgeführt wird.throw— selbst eine Exception auslösen.- Die Exception-Klasse — der Basistyp und seine Methoden.
- Exceptions in PHP — das größere Bild der Fehlerbehandlung.
set_exception_handler()— Exceptions abfangen, die jedentry-Block umgehen.