Signatur
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;
}
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
// 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.