Fehlerbehandlung
In diesem Thema wollen wir uns mit der Behandlung und Behebung von Fehlern beschäftigen. Grundsätzlich muss strikt zwischen PHP-Fehlern und Exceptions unterschieden werden, weshalb wir diese in diesem Thema auch getrennt haben.
PHP-Fehlermeldungen
PHP löst in einigen Fällen Fehler aus. Dabei handelt es sich immer um Laufzeitfehler (da PHP-Code nicht kompiliert wird). Bei Laufzeitfehlern kann es sich um Syntaxfehler (da PHP zur Laufzeit interpretiert wird) handeln, aber auch um andere Fehler wie Division durch 0, ungültige Zugriffe (vor allem bei Objekten), Fehler beim Öffnen, Lesen oder Schreiben einer Datei, Fehler beim Herstellen der Datenbankverbindung uvm.. Dieses Meldungssystem von PHP wird auch Error-Reporting-System bezeichnet. Die folgende Tabelle zeigt die wichtigsten Typen von Fehlern:
Wert | Konstante | Beschreibung |
---|---|---|
1 | E_ERROR | fataler Fehler, dies hat einen Skriptabbruch zur Folge |
2 | E_WARNING | Warnung |
4 | E_PARSE | Fehler beim Interpretieren, dies hat einen Skriptabbruch zur Folge |
8 | E_NOTICE | Benachrichtigungen |
2048 | E_STRICT | Benachrichtigungen über Codeverbesserungen |
8192 | E_DEPRECATED | Benachrichtigungen über veraltete Codebestandteile |
32767 | E_ALL | alle Fehler, Warnungen und Benachrichtigungen |
Mit Hilfe der Funktion error_reporting()
können Sie steuern, welche Fehlermeldungen ausgegeben bzw. gemeldet
werden sollen. Als Parameter wird der sogenannte Fehler-Level übergeben. Davon kann als Wert ein nummerischer Wert oder
eine Konstante aus der obigen Tabelle verwendet werden. Die Werte können bei Bedarf bitweise verundet und verodert werden.
Für Entwicklungszwecke eignet sich die Verwendung des Fehler-Levels E_ALL
.
<?php error_reporting(E_ALL); ?>
Die Funktion error_log()
erlaubt es, Fehlermeldungen auszulösen. Der Funktion muss eine Nachricht (Datentyp
String
) übergeben werden. Optional kann ein Typ (message_typ
) und ein Ziel (destination
)
übergeben werden. Mit dem Parameter message_typ
wird festgelegt, wo der Fehler hingesendet wird: PHP-Log-System
(0), E-Mail versenden (1), anhängen an Datei (3). Der destination
-Parameter wird nur für den E-Mail-Versand
(als E-Mail-Adresse) und beim Anhängen an eine Datei (als Dateiname) benötigt.
<?php error_log('Fehler bei der Datenbankverbindung!', 1, 'info@example.com'); ?>
Wenn Sie Ihre Webseite veröffentlichen, sollten Sie vor allem danach schauen, Fehler zu behandeln, indem Sie z. B. eine
Variable auf null
oder vor einer Division auf 0 prüfen. Trotzdem kann es natürlich immer wieder zu Fehlern kommen
(die entweder nicht abgefangen wurden oder nicht abgefangen werden können), die dem Besucher natürlich nicht angezeigt
werden sollten. Der „einfachste Weg“, der auch in vielen Foren als Lösung vorgeschlagen wird, ist die Deaktivierung der
Fehler-Benachrichtigung mittels der Funktion error_reporting()
. Das Problem an dieser Lösung ist, dass
Fehler zwar nicht mehr angezeigt aber auch nicht mehr gemeldet werden. Dies hat zur Folge, dass Fehler im Serverlogfile
nicht mehr geloggt werden. So treten auf Ihrer Webseite u. U. Fehler auf, die Sie nie bemerken würden. Um dieses Problem zu
lösen, stellen Sie die Fehler-Benachrichtigung mittels der Funktion error_reporting()
so ein wie gewünscht
(z. B. nur Fehler und Warnungen). Nun sollte die PHP-Einstellung display_errors
auf 0
und die
Einstellung log_errors
auf 1
gesetzt werden. Dadurch werden Fehler nicht mehr angezeigt jedoch geloggt.
Beide Einstellungen können mittels der Funktion ini_set()
oder innerhalb der Konfigurationsdatei php.ini
geändert werden. Wird die Funktion ini_set()
verwendet, so gilt die Einstellung nur für die Ausführung des
aktuellen Skripts.
<?php ini_set('display_errors', '0'); ini_set('log_errors', '1'); ?>
Exception-Handling
Nun wollen wir uns noch mit dem sogenannten Exception-Handling (zu Deutsch Ausnahmebehandlung) beschäftigen. Viele
PHP-Funktionen lösen keine Ausnahmen (engl. exceptions) aus, sondern nutzen das Error-Reporting-System, welches wir
weiter oben bereits beschrieben haben, um Fehler „an den Programmierer“ weiterzugeben. Einige neue „moderne“ PHP-Komponenten,
wie z. B. die PDO
-Klasse für Datenbankzugriffe, nutzen jedoch das Exception
-System. Des Weiteren ist
es Ihnen möglich, Ausnahmen selber auszulösen bzw., wie es in der Fachsprache heißt, zu werfen.
Exceptions können von Funktionen, welche im PHP-Interpreter integriert sind oder von selbst geschriebenen Funktionen „geworfen“
(also ausgelöst) werden. Exceptions sollten unbedingt abgefangen werden, da andernfalls ein fataler PHP-Fehler
(E_ERROR
) gemeldet wird, was ein Skriptabbruch zur Folge hat. Um eine Exception abzufangen, muss der Code, welcher
eine Exception auslösen kann, innerhalb eines try
-Blocks notiert werden. Hinter dem try
-Block folgt ein
catch
-Block. Der Code im catch
-Block enthält einen Programmcode zur Fehlerbehandlung. Dieser
wird nur ausgeführt, wenn eine Exception geworfen wurde. Um auf die Informationen der Exceptions zuzugreifen, werfen alle
Exceptions ein Objekt mit Fehlerinformationen. Darauf kann vom catch
-Block zugegriffen werden. Alle
Ausnahmeobjekte sind dabei eine Instanz von der Klasse Exception
oder von einer der Unterklassen (z. B.
PDOException
). Um z. B. auf die Fehlermeldung zuzugreifen, können wir die Funktion getMessage()
aufrufen. Mit Hilfe der Funktionen getFile()
und getLine()
kann der Dateiname und die dazugehörige
Zeile abgerufen werden, in welcher die Ausnahme geworfen wurde.
<?php try { // Code der Exceptions wirft } catch (Exception $ex) { // Code zur Behandlung der Fehler } ?>
Nach dem try
- und catch
-Block kann noch zusätzlich ein finally
-Block folgen. Der Code
im finally
-Block wird nach der vollständigen Ausführung des try
-Blocks oder des catch
-Blocks
ausgeführt. Der finally
-Block dient grundsätzlich zur Freigabe von Ressourcen.
<?php try { // Code der Exceptions wirft } catch (Exception $ex) { // Code zur Behandlung der Fehler } finally { // Code zur Freigabe von Ressourcen } ?>
Um eine Ausnahme zu werfen, notieren wir das Schlüsselwort throw
, gefolgt von einem Objekt der Klasse
Exception
oder einer der Unterklassen. Üblicherweise wird die Objektinstanziierung direkt mit dem
throw
-Statement ausgeführt. Dem Konstruktor der Exception
-Klasse kann optional eine Nachricht
übergeben werden, welche mittels der Funktion getMessage()
abgerufen werden kann.
<?php throw new Exception('Fehler bei der Datenbankverbindung!'); ?>
Das folgende Beispiel zeigt eine einfache und doch reelle Variante, wie Ausnahmen verwendet werden:
<?php $a = 4; $b = 0; try { if ($b == 0) throw new Exception('Division durch 0 nicht erlaubt!'); echo $a / $b; } catch (Exception $ex) { echo 'Meldung: '.$ex->getMessage(); } ?>
Wichtig: Auch wenn es im ersten Moment vielleicht etwas verwirrend klingen mag, Exceptions zu werfen nur um diese später wieder abfangen zu können, kann es gerade bei größeren Projekten Sinn machen.