Start · Sprachen · PHP · Referenz · Throwable

Throwable

Klasse

Basis-Interface aller werfbaren Objekte in PHP – implementiert von <code>Error</code> und <code>Exception</code>.

seit PHP 7.0.0 Kategorie: misc

Signatur

interface Throwable

Beschreibung

Throwable ist das oberste Interface der PHP-Fehlerhierarchie und wurde mit PHP 7.0 eingeführt. Es wird von zwei großen Zweigen implementiert: Exception (für anwendungsseitige Ausnahmen) und Error (für interne PHP-Fehler wie TypeError, ParseError oder ArithmeticError). Alles, was mit throw geworfen oder mit catch gefangen werden kann, muss dieses Interface implementieren.

Das Interface selbst kann von Benutzerklassen nicht direkt implementiert werden – eigene Klassen müssen stattdessen entweder Exception oder Error erweitern. Durch den gemeinsamen Typ Throwable lassen sich jedoch in einem einzigen catch-Block sowohl Exceptions als auch Errors abfangen, was besonders für zentrale Fehlerbehandlungsroutinen (z. B. in Frameworks oder beim Logging) nützlich ist.

Das Interface definiert folgende Methoden: getMessage(), getCode(), getFile(), getLine(), getTrace(), getTraceAsString(), getPrevious() und __toString(). Diese Methoden sind bei allen Throwables garantiert verfügbar.

Typdeklarationen mit Throwable ermöglichen es, Funktionen und Methoden zu schreiben, die sowohl Exception- als auch Error-Objekte akzeptieren, ohne auf eine konkrete Klasse festgelegt zu sein.

Beispiele

Beide Zweige mit Throwable fangen

<?php
function riskyOperation(): void {
    // Simuliert einen PHP-internen Fehler (Error)
    $result = intdiv(10, 0);
}

try {
    riskyOperation();
} catch (\Throwable $t) {
    echo get_class($t) . ': ' . $t->getMessage() . PHP_EOL;
    echo 'Datei: ' . $t->getFile() . ' (Zeile ' . $t->getLine() . ')' . PHP_EOL;
}
DivisionByZeroError: Division by zero Datei: /path/to/script.php (Zeile 4)

Zentrales Logging mit Throwable als Typdeklaration

<?php
function logThrowable(\Throwable $t, string $channel = 'app'): void {
    $entry = sprintf(
        '[%s] [%s] %s in %s:%d\nTrace:\n%s',
        strtoupper($channel),
        get_class($t),
        $t->getMessage(),
        $t->getFile(),
        $t->getLine(),
        $t->getTraceAsString()
    );
    // In der Praxis: error_log($entry) oder PSR-3-Logger
    echo $entry . PHP_EOL;
}

try {
    throw new \InvalidArgumentException('Ungültiger Wert', 42);
} catch (\Throwable $t) {
    logThrowable($t);
}
[APP] [InvalidArgumentException] Ungültiger Wert in /path/to/script.php:15 Trace: #0 {main}

Eigene Exception-Klasse — kein direktes Implementieren von Throwable

<?php
// RICHTIG: von Exception oder Error erben
class DomainException extends \Exception {
    public function __construct(string $message, private readonly string $domain = '') {
        parent::__construct($message);
    }

    public function getDomain(): string {
        return $this->domain;
    }
}

function process(string $input): void {
    if ($input === '') {
        throw new DomainException('Eingabe darf nicht leer sein', 'user-input');
    }
    echo 'Verarbeite: ' . $input . PHP_EOL;
}

try {
    process('');
} catch (\Throwable $t) {
    echo $t->getMessage() . PHP_EOL;
    if ($t instanceof DomainException) {
        echo 'Domäne: ' . $t->getDomain() . PHP_EOL;
    }
}
Eingabe darf nicht leer sein Domäne: user-input

// Wichtig · Fallstricke

Direktes Implementieren nicht möglich: Der Versuch, Throwable direkt zu implementieren (class Foo implements Throwable), führt zu einem fatalen Fehler. Eigene Klassen müssen immer Exception oder Error erweitern.

Fangstrategie: catch (\Throwable $t) fängt alles – inklusive TypeError, ParseError und anderer PHP-interner Fehler. Dies ist in Produktivsystemen mit Bedacht einzusetzen, da auch kritische Fehler unterdrückt werden können. Für konkrete Fehlerbehandlung immer spezifischere Klassen bevorzugen.

PHP < 7: In PHP 5 existiert Throwable nicht. Error-Objekte existieren dort ebenfalls nicht – PHP-Fehler wurden als traditionelle Fehler (nicht als Exceptions) behandelt. Code, der Throwable verwendet, ist daher auf PHP 7.0+ beschränkt.