Start · Sprachen · PHP · Referenz · PDOException

PDOException

Klasse

Repräsentiert einen Fehler, der von der PDO-Datenbankabstraktion ausgelöst wird, und enthält spezifische SQL-Statusinformationen.

seit PHP 5.1.0 Kategorie: error

Signatur

class PDOException extends RuntimeException

Beschreibung

PDOException wird von PDO ausgelöst, wenn im Fehlerbehandlungsmodus PDO::ERRMODE_EXCEPTION ein Datenbankfehler auftritt – etwa bei fehlgeschlagenen Verbindungen, ungültigem SQL oder verletzten Constraints. Die Klasse erbt von RuntimeException und ergänzt diese um das Attribut $errorInfo, das ein dreielementiges Array mit SQLSTATE-Code, Treiber-Fehlercode und Treiber-Fehlermeldung enthält.

Der in getMessage() zurückgegebene Text entspricht dem Fehler des PDO-Treibers. Der SQLSTATE-Code (z. B. 23000 für Constraint-Verletzungen) ist zusätzlich über $errorInfo[0] abrufbar und ermöglicht eine feinere Fehlerunterscheidung im catch-Block.

Wichtig: PDOException sollte ausschließlich von PDO selbst ausgelöst werden. Eigener Code sollte stattdessen passende domänenspezifische Ausnahmen werfen. Der Ausnahmen-Modus wird per PDO::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) aktiviert, ist aber seit PHP 8.0 der Standard.

Da PDOException von RuntimeException erbt, können alle Standard-Methoden der Ausnahme-Hierarchie genutzt werden: getMessage(), getCode(), getFile(), getLine() sowie getTrace().

Beispiele

Datenbankfehler abfangen und SQLSTATE auslesen

<?php
try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'root', 'geheim');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Absichtlich fehlerhaftes SQL
    $pdo->exec('INSERT INTO nicht_vorhanden (id) VALUES (1)');
} catch (PDOException $e) {
    echo 'Fehler: ' . $e->getMessage() . PHP_EOL;
    echo 'SQLSTATE: ' . $e->errorInfo[0] . PHP_EOL;
    echo 'Treiber-Code: ' . $e->errorInfo[1] . PHP_EOL;
    echo 'Treiber-Meldung: ' . $e->errorInfo[2] . PHP_EOL;
}
Fehler: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testdb.nicht_vorhanden' doesn't exist SQLSTATE: 42S02 Treiber-Code: 1146 Treiber-Meldung: Table 'testdb.nicht_vorhanden' doesn't exist

Verbindungsfehler und Constraint-Verletzung unterscheiden

<?php
function insertUser(PDO $pdo, int $id, string $name): void
{
    try {
        $stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (:id, :name)');
        $stmt->execute([':id' => $id, ':name' => $name]);
        echo "Benutzer $name eingefügt." . PHP_EOL;
    } catch (PDOException $e) {
        $sqlState = $e->errorInfo[0] ?? '';

        if ($sqlState === '23000') {
            // Primärschlüssel- oder UNIQUE-Verletzung
            echo "Benutzer mit ID $id existiert bereits." . PHP_EOL;
        } else {
            // Unbekannter Fehler – weiterwerfen
            throw $e;
        }
    }
}

$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'root', 'geheim');
insertUser($pdo, 1, 'Alice');
insertUser($pdo, 1, 'Bob'); // Doppelter Primärschlüssel
Benutzer Alice eingefügt. Benutzer mit ID 1 existiert bereits.

// Wichtig · Fallstricke

Sicherheitshinweis: $e->getMessage() und $e->errorInfo können sensible Informationen enthalten (Tabellennamen, Spaltennamen, interne Datenbankstruktur). Diese Angaben dürfen niemals ungefiltert an den Endnutzer ausgegeben werden – nur ins Server-Log schreiben und dem Nutzer eine generische Fehlermeldung zeigen.

Fehlerbehandlungsmodus: Seit PHP 8.0 ist PDO::ERRMODE_EXCEPTION der Standard-Fehlermodus. In älteren PHP-Versionen musste er explizit gesetzt werden, sonst wurden Fehler stillschweigend ignoriert oder nur über errorInfo() abrufbar.

Nicht selbst werfen: Eigener Anwendungscode sollte keine PDOException instanziieren oder werfen. Stattdessen eigene Ausnahmenklassen (z. B. DatabaseException) definieren, die ggf. die PDOException als Vorgänger ($previous) übergeben.