Fehlerbehandlung
als Präsentation ▻Wir haben bisher keinerlei Rücksicht darauf genommen, dass ein Fehler auftreten könnte. Zum Beispiel könnte beim Einfügen in die Datenbank ein Constraint verletzt werden und das Einfügen fehlschlagen. Wie behandelt man diesen Fall in PHP?
▻Exceptions in PHP
Folgende Beschreibung ist aus dem PHP Handbuch übernommen:
PHP 5 hat ein Exceptionmodell ähnlich dem anderer Programmiersprachen. Eine Exception kann in PHP
geworfen (throw
) und abgefangen (catch
) werden. Um das Fangen potentieller Exceptions zu
ermöglichen, wird der jeweilige Code mit einem try
-Block umschlossen.
Die normale Programmausführung (wenn keine Exception innerhalb des try
-Blockes geworfen wird)
wird nach dem letzten catch
-Block fortgesetzt.
Exceptions können innerhalb eines catch
-Blockes geworfen (oder weitergeworfen) werden.
Wenn eine Exception geworfen wird, wird der Programmcode der auslösenden Anweisung nicht ausgeführt,
und PHP versucht, den ersten passenden catch
-Block zu finden. Falls eine Exception gar
nicht abgefangen wird, wird ein fataler Fehler mit einer “Uncaught Exception …“-Nachricht ausgegeben
Php Code Beispiel für Exception-Handling in PHP
<?php function compute($x) { if ($x == 0) { throw new Exception('Illegal Input: 0.'); } return 1 / $x; } try { echo compute(5) . "\n"; echo compute(0) . "\n"; } catch (Exception $e) { echo 'Exception abgefangen: ', $e->getMessage(), "\n"; } // output: // 0.2 // Exception abgefangen: Illegal Input: 0 ?>
Verwendung von Exceptions für die Datenbank
PDO wirft normalerweise keine Exceptions. Ihre Verwendung muss erst mit dem
Attribut ERRMODE
aktiviert werden:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
In folgendem Beispiel soll ein Datensatz (plus abhängige Daten) dargestellt werden. Dabei könnte schon beim Verbindungsaufbau mit der Datenbank ein Fehler auftreten, oder bei einzelnen Abfragen.
Php Code Datenbank-Abfrage mit Exception Handling als Fehlerbehandlung
$get_id = $_GET['id']; try{ include "config.php"; if( ! $DSN ) { throw(new Exception( "DB nicht konfiguriert. config.php anlegen!" )); } $dbh = new PDO($DSN, $DB_USER, $DB_PASS); /* das folgende Attribut aktiviert die Exceptions */ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $sth = $dbh->prepare( "SELECT * FROM users WHERE id=?" ); $sth->execute(array($get_id)); $p = $sth->fetch(); // wirklich nicht in der Datenbank if( $p === false ) { throw (new Exception( "Kein Person Nr. $get_id in der DB." )); } // Profil verborgen if( !$p->profile_visible ) { throw (new Exception( "Kein Person Nr. $get_id in der DB." )); } $sth = $dbh->prepare( " .... " ); $sth->execute(array($get_id)); $projects = $sth->fetchAll(); } catch( Exception $e ) { include "header.php"; echo "<h1>Problem mit der Datenbank</h1>" ; echo "<p>Bitte versuchen Sie es später wieder.</p>" ; echo "<!--" . $e->getMessage() . "-->"; include "footer.php"; exit; } /* hier folgt die normale Ausgabe der Seite */
In diesem Beispiel erfolgt die ganze Arbeit mit der Datenbank
bevor die Ausgabe beginnt. Im catch
-Block wird eine Webseite
erzeugt, die gar nichts mit der “normalen” Ausgabe der Seite zu
tun hat.
Exkurs: Exceptions in Javascript
Die Verwendung und Schreibweise ist in Javascript so ähnlich, dass es sich gar nicht lohnt näher darauf einzugehen. Siehe Rauschmayer(2012): Ausnahmebehandlung in JavaScript in mag.js Nr.1