W3docs

catch

Das PHP-Schlüsselwort catch fängt Ausnahmen aus try-Blöcken ab und ermöglicht eine gezielte Fehlerbehandlung im Code.

Das PHP-Schlüsselwort catch

Wenn Code innerhalb eines try-Blocks auf eine Ausnahme trifft — ein object, das signalisiert, dass etwas schiefgelaufen ist — wird die Ausführung gestoppt und PHP sucht nach einem passenden catch-Block, um sie zu behandeln. Das Schlüsselwort catch gibt den Typ der Ausnahme an, den es abfangen kann, und bindet das geworfene object an eine Variable, damit Sie es untersuchen können. Ohne ein catch wird eine nicht abgefangene Ausnahme zu einem schwerwiegenden Fehler und bricht das Skript ab.

Diese Seite erklärt die catch-Syntax, wie PHP entscheidet, welcher Block ausgeführt wird, wie man Details der abgefangenen Ausnahme ausliest und welche häufigen Muster (mehrere catch-Blöcke, Union-Typen, Weiterwurf) Sie im echten Code einsetzen werden.

Syntax

Ein catch-Block folgt immer auf einen try-Block. Er deklariert einen Ausnahmetyp und eine Variable, die das geworfene object empfängt:

<?php

try {
    // Code that may throw an exception
} catch (Exception $e) {
    // Runs only if a matching exception is thrown above
    echo $e->getMessage();
}

PHP trifft einen catch-Block, wenn das geworfene object eine Instanz von dem deklarierten Typ ist. Da jede eingebaute Ausnahme die Basisklasse Exception erweitert (und beide das Interface Throwable implementieren), fängt catch (Exception $e) die meisten Ausnahmen ab. Das Abfangen von Throwable erfasst zusätzlich Error-Objekte wie TypeError und DivisionByZeroError.

Sie können catch mit einem finally-Block kombinieren, um Bereinigungscode auszuführen, unabhängig davon, ob eine Ausnahme aufgetreten ist oder nicht.

Ein funktionierendes Beispiel

Die folgende Funktion wirft eine Ausnahme, wenn sie aufgefordert wird, durch null zu dividieren. Der catch-Block fängt diese Ausnahme ab und meldet sie, anstatt das Skript abstürzen zu lassen:

<?php

function divide($numerator, $denominator)
{
    if ($denominator == 0) {
        throw new InvalidArgumentException("Division by zero.");
    }
    return $numerator / $denominator;
}

try {
    echo divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo "Error: " . $e->getMessage();
}

// Output: Error: Division by zero.

Beachten Sie, dass das Skript nach dem catch weiter ausgeführt wird — die Kontrolle wird auf der Zeile nach der try/catch-Struktur fortgesetzt, anstatt abzubrechen.

Details der abgefangenen Ausnahme auslesen

Die Variable in einem catch-Ausdruck ($e oben) ist das exception-object selbst. Es stellt Methoden bereit, die beschreiben, was passiert ist:

<?php

try {
    throw new RuntimeException("Disk is full", 28);
} catch (RuntimeException $e) {
    echo $e->getMessage();  // Disk is full
    echo "\n";
    echo $e->getCode();     // 28
    echo "\n";
    echo $e->getLine();     // 4  (line where it was thrown)
}
MethodeRückgabewert
getMessage()Die menschenlesbare Fehlermeldung
getCode()Der ganzzahlige Fehlercode, der an den Konstruktor übergeben wurde
getFile()Die Datei, in der die Ausnahme erstellt wurde
getLine()Die Zeilennummer, an der sie geworfen wurde
getTrace()Der Stack-Trace als array
getPrevious()Die vorherige Ausnahme (für verkettete Ausnahmen)

Mehrere Ausnahmetypen abfangen

Wenn ein try-Block auf verschiedene Weisen fehlschlagen kann, listen Sie mehrere catch-Blöcke auf. PHP prüft sie von oben nach unten und führt den ersten passenden aus, daher sollten spezifischere Typen vor den allgemeineren stehen:

<?php

try {
    // Code that may throw different exceptions
    throw new InvalidArgumentException("bad input");
} catch (InvalidArgumentException $e) {
    echo "Invalid argument: " . $e->getMessage();
} catch (RuntimeException $e) {
    echo "Runtime problem: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something else: " . $e->getMessage();
}

// Output: Invalid argument: bad input

Wenn catch (Exception $e) zuerst käme, würde es alles abfangen, und die spezifischeren Blöcke darunter würden niemals ausgeführt werden.

Union-catch (PHP 7.1+)

Wenn zwei verschiedene Ausnahmetypen identisch behandelt werden müssen, kombinieren Sie sie mit einem Pipe-Zeichen |, anstatt den Block zu duplizieren:

<?php

try {
    throw new RuntimeException("connection reset");
} catch (InvalidArgumentException | RuntimeException $e) {
    echo "Handled: " . $e->getMessage();
}

// Output: Handled: connection reset

Catch ohne Variable (PHP 8.0+)

Wenn Sie das Ausnahme-object nicht benötigen, können Sie die Variable vollständig weglassen:

<?php

try {
    throw new Exception("ignored details");
} catch (Exception) {
    echo "An error occurred, retrying...";
}

// Output: An error occurred, retrying...

Weiterwurf und Ausnahmen-Verkettung

Manchmal sollte ein catch-Block das Problem protokollieren und dann weitergeben — oder eine Low-Level-Ausnahme in eine aussagekräftigere einwickeln. Übergeben Sie das Original als drittes Konstruktorargument, um die Kette zu erhalten:

<?php

try {
    try {
        throw new RuntimeException("low-level failure");
    } catch (RuntimeException $e) {
        // Wrap and re-throw with context preserved
        throw new Exception("High-level operation failed", 0, $e);
    }
} catch (Exception $e) {
    echo $e->getMessage();              // High-level operation failed
    echo "\n";
    echo $e->getPrevious()->getMessage(); // low-level failure
}

Best Practices

  • Fangen Sie den engsten Typ ab, den Sie behandeln können. Ein pauschales catch (Throwable $e) kann Fehler verbergen, indem es Programmierfehler schluckt, die Sie eigentlich beheben wollten.
  • Reihenfolge: Spezifisches vor Allgemeinem. Spezifische Unterklassen müssen vor ihren übergeordneten Typen stehen.
  • Lassen Sie einen catch-Block niemals leer. Das stille Verwerfen einer Ausnahme macht Fehler unsichtbar; loggen Sie sie zumindest.
  • Werfen Sie, statt Fehler-Flags zurückzugeben. Kombinieren Sie catch mit throw, damit Aufrufer Fehler nicht versehentlich ignorieren können.
  • Verwenden Sie finally für die Bereinigung (Schließen von Dateien, Freigeben von Sperren), die sowohl auf dem Erfolgs- als auch auf dem Fehlerpfad ausgeführt werden muss.

Verwandte Themen

Übungen

Übung
Was passiert, wenn eine Ausnahme in PHP geworfen und nicht abgefangen wird?
Was passiert, wenn eine Ausnahme in PHP geworfen und nicht abgefangen wird?
Was this page helpful?