Interne Fehlerbehandlung von PHP

Werbung

Ein Programm oder ein größeres Skript auf Anhieb fehlerfrei zu programmieren, ist fast unmöglich. Es schleichen sich Tipp- oder Logikfehler in den Quellcode ein und stören den reibungslosen Ablauf. Auftretende Fehler müssen vom Programmierer abgefangen, analysiert und behandelt werden.

Macht man das nicht, werden Fehler auf der Webseite ausgegeben. Das sieht nicht schön aus und zerstört zumeist auch das Layout der Seite. Schwerwiegende Fehler sorgen zudem dafür, dass die Ausführung des Quellcodes komplett abgebrochen wird.

Fehlermeldungen

Die Fehlermeldungen von PHP sollten niemals unterdrückt oder ignoriert werden, nur um die Seite zum Laufen zu bringen. Skript und Server sollten so programmiert und konfiguriert sein, dass der zufällige Besucher der Webseite zumindest eine optisch angemessene und inhaltlich sinnvolle Fehlermeldung zu Gesicht bekommt, bis das Problem behoben wurde.

PHP intern gibt es verschiedene Schweregrade von Fehlermeldungen. Unterschieden werden diese in die Hauptkategorien Hinweis (E_NOTICE), Warnung (E_WARNING) und schwerwiegender Fehler (E_ERROR). Die einfachste der drei Kategorien stellen die E_NOTICE-Fehler dar. Diese stören eher selten den Ablauf eines Skriptes. Solch ein Fehler tritt etwa auf, wenn eine nicht initialisierte Variable um eins erhöht werden soll, wie folgender Codeabschnitt zeigt:


<?php
	$i++;
?>

Wird der Inhalt der Variable ausgeben, so beinhaltet die Variable i nun die Zahl 1. Um hier den E_NOTICE Fehler zu vermeiden, sollte die Variable i richtig initialisiert werden. So müsste das Skript dann aussehen:


<?php
	$i = 0;
	$i++;
?>

Hilfreich sind diese Fehlermeldungen, wenn besonderen Wert auf ein ”sauberes” Skript gelegt wird. Es werden etwa auch Tippfehler bei Variablennamen mit einem E_NOTICE-Fehler offen gelegt. Allerdings ist diese Fehlerkategorie standardmäßig bei PHP nicht aktiviert.

In der nächsten Kategorie warten die E_WARNING-Fehler auf eine Behebung. Auch diese Fehler verhindern den Ablauf eines Skriptes nicht. Hierbei wird dem Entwickler (aber auch dem Besucher) ausgegeben, dass der Code nicht einwandfrei funktioniert. Beispielsweise tritt dieser Fehler auf, wenn man versucht, eine Datei mit include() einzubeziehen, die gar nicht existiert, oder wenn mittels mysql_connect() die Verbindung zu einer Datenbank mit falschen Zugangsdaten geöffnet wird.

Wird das Skript erst gar nicht ausgeführt oder zur Laufzeit abgebrochen, kann ein E_ERROR-Fehler die Ursache sein. Der folgende Code-Abschnitt zeigt zwei Fehler, die einen E_ERROR Fehler erzeugen:


<?php
	function ausgeben($name)
	{
		echo $name
	}

	augeben('Jan');
?>

Bei der Ausführung wird das fehlende Semikolon hinter der Variable $name bemängelt. Auch kann der Aufruf der Funktion nicht glattgehen, da durch einen Tippfehler die Funktion ”augeben” nicht gefunden wurde. Wird das Semikolon eingefügt und der Tippfehler behoben, funktioniert das Skript einwandfrei. Ein E_ERROR kann viele Ursachen haben, wie zum Beispiel die Initialisierung einer nicht vorhandenen Klasse oder etwa das falsche Setzen von geschweiften Klammern.

Neben den drei bisher beschriebenen Fehlertypen gibt es noch weitere:

  • E_PARSE – Der vom Parser erzeugte Fehler tritt dann auf, wenn ein Syntaxfehler im Skript vorhanden ist. Dies geschieht etwa dann, wenn ein Semikolon fehlt oder vor einer Variable kein $ geschrieben wird. Das Skript wird bei diesem Fehler nicht ausgeführt.
  • E_COMPILE_WARNING – Eine zur Übersetzungszeit von der Zend-Engine erzeugte Warnung.
  • E_COMPILE_ERROR – Ein zur Übersetzungszeit von der Zend-Engine erzeugter schwerwiegender Fehler.
  • E_CORE_ERROR – Kann PHP nicht richtig gestartet werden, erzeugt der Kern von PHP einen schwerwiegenden Fehler.
  • E_USER_ERROR – Benutzerdefinierter, mit trigger_error() erzeugter, schwerwiegender Fehler
  • E_CORE_WARNING – Funktionsweise wie E_WARNING, vom Kern von PHP erzeugt.
  • E_USER_WARNING – Benutzerdefinierte, mit trigger_error() erzeugte, Warnung
  • E_STRICT – Seit PHP 5 werden Entwickler bei der Optimierung des eigenen Codes unterstützt. Dieser Fehlertyp gibt Hinweise auf veraltete Funktionen, um so eine bestmögliche Kompatibilität sicher zu stellen.
  • E_USER_NOTICE – Benutzerdefinierter, mit trigger_error() erzeugter, Hinweis
  • E_DEPRECATED – Seit PHP 5.3 nutzbar. Ausgegeben werden Hinweise zu Codebestandteilen die bei folgenden PHP Versionen nicht mehr funktionieren.

Anzeige

Bei der Entwicklung einer Webseite ist es also hilfreich, alle Fehler (auch die E_NOTICE) auszugeben. Um das Verhalten bei Fehlern zu konfigurieren, ist eine Änderung in der php.ini nötig. Darin lässt sich im Bereich ”Error handling and logging” (zumeist) folgender Eintrag finden:


error_reporting = E_ALL & ~E_NOTICE

Diese Zeile besagt, dass alle Fehler außer der E_NOTICE-Fehler ausgeben werden. Für einen sauberen Code sollte man das ”& ~E_NOTICE” aus der Zeile löschen.

Geht die Webseite in den Produktivbetrieb, sollte allerdings eine andere Konfiguration des Error Reportings genutzt werden. Nun ist es vorteilhaft, dass der Besucher keinerlei Fehlermeldungen zu Gesicht bekommt. Um die Anzeige der Fehlermeldungen zu unterdrücken, sollte die php.ini folgende Einträge beinhalten:


error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log  = /eigener/pfad/fehler.log

Der Besucher bekommt nun keine Fehlermeldungen mehr zu sehen, da diese durch display_errors=Off unterdrückt werden. Um allerdings weiter auftretende Fehler zu protokollieren, werden alle Fehler durch log_errors=On in einem Logfile gespeichert. Der Pfad zum Logfile wird explizit durch error_log=/eigener/pfad/dateiname.log angegeben. Hier sollte man aber beachten, dass der Server entsprechende Schreib-Rechte für das Verzeichnis benötigt.

Auch das Erstellen benutzerdefinierte Texte im Log ist möglich. Hierzu kann man die PHP-Funktion error_log() einsetzen. Übergeben wird bei der Funktion der jeweilige Text oder optional weitere Parameter wie etwa der Nachrichtentyp. Das Einfügen einer einfachen Nachricht in das Log geschieht wie folgt:


<?php
	error_log('Hier steht ein beliebiger Text');
?>

Doch nicht jeder verfügt über einen eigenen Server, bei der die php.ini leicht geändert werden kann. Um auch dabei die Fehlerbehandlung entsprechend zu konfigurieren, gibt es zwei Umwege. Einerseits über die .htaccess oder über die PHP-Funktion ini_set().

Konfiguration der php.ini mittels .htaccess

Die Methode über die .htaccess funktioniert ähnlich wie bei der php.ini. Beachten sollte man allerdings, dass die Namen der Konstanten wie E_ALL, E_ERROR oder E_NOTICE nicht genutzt werden können. Jede Konstante hat jedoch einen bestimmten Wert. So steht die 2047 zum Beispiel für E_ALL. Die Werte der jeweiligen Konstante ist folgender Tabelle zu entnehmen:

Wert Konstante
1 E_ERROR
2 E_WARNING
4 E_PARSE
8 E_NOTICE
16 E_CORE_ERROR
32 E_CORE_WARNING
64 E_COMPILE_ERROR
128 E_COMPILE_WARNING
256 E_USER_ERROR
512 E_USER_WARNING
1028 E_USER_NOTICE
2047 E_ALL

Um etwa alle Fehler anzuzeigen, muss folgende Zeile in die .htaccess geschrieben werden:


php_value error_reporting 2047

Soll bei der Ausgabe der Fehlermeldungen differenziert werden, müssen die entsprechenden Werte der jeweiligen Konstanten von E_ALL abgezogen werden. Wenn etwa die Standardeinstellung E_ALL & ~E_NOTICE verlangt wird, muss in der .htaccess folgende Zeile stehen:


php_value error_reporting 2039

Da E_NOTICE den Wert 8 besitzt, wird 2047 – 8 gerechnet. Auch der umgekehrte Weg funktioniert. Soll nur der Fehler E_WARNING und E_NOTICE sichtbar sein, aber alle anderen nicht, so muss der Wert der jeweiligen Konstante addiert werden. Gerechnet wird also 2 + 8 = 10. Die .htaccess muss also den folgenden Eintrag beinhalten:


hp_value error_reporting 10

Diese Einstellungen sind allerdings nur für die Entwicklung relevant. Im Produktivbetrieb sollten wie bei der Konfiguration direkt über die php.ini alle Fehler unterdrückt, aber protokolliert werden. Um dies zu realisieren, muss die .htaccess folgende Einträge bieten:


php_value error_reporting 2047
php_value display_errors 0
php_value log_errors 1
php_value error_log /eigener/pfad/fehler.log

Hierbei kann nicht mit den Konstanten On und Off gearbeitet werden. Für On wird eine 1, für Off eine 0 verwendet.

Konfiguration der php.ini mittels ini_set()

Die Funktion ini_set() wird direkt im PHP-Skript verwendet. Zu der Laufzeit des Skriptes wird mit dieser Funktion der entsprechende Eintrag in der php.ini überschrieben. Dies ist allerdings nur eine temporäre, auf das jeweilige Skript beschränkte, Einstellung. Dauerhaft überschreibt die Funktion ini_set() die php.ini also nicht. Um alle Fehler anzeigen zu lassen, wird folgende Zeile in das PHP-Skript eingefügt:


ini_set('error_reporting', E_ALL);

Um das Verhalten für Fehlermeldungen nicht in jede Datei schreiben oder die Dateien für den späteren Produktivbetrieb nicht wieder umschreiben zu müssen, ist es sinnvoll, den Code für die Fehlerbehandlung in eine einzelne Datei zu schreiben und diese mit include() zu laden. Für den Produktivbetrieb sollte folgender Code genutzt werden:


ini_set('error_reporting', E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1); ini_set('error_log', '/eigener/pfad/fehler.log');

Weitere Beiträge:

, ,

12 Kommentare zu Interne Fehlerbehandlung von PHP

  1. André 20. Februar 2009 at 09:39 #

    Schöne Übersicht, danke! :)

  2. Günther Stadler 20. Februar 2009 at 12:00 #

    Welche PHP-Version behandelt der Artikel denn eigentlich?
    Inzwischen gibt es einige neue E_*-Konstanten, und PHP5 ist ja nun doch schon ein ganzes Zeiterl heraußen…

    Auf http://at.php.net/error_reporting sind 4 weitere Konstanten gelistet.

    Ich frage mich gerade, woher der Autor des Artikels die Informationen bezieht. Auch auf der deutschen Seite des PHP-Manuals (die leider manchmal etwas an Aktualität hinterher hinkt) sind die neuen Konstanten gelistet…

  3. iflow 20. Februar 2009 at 12:29 #

    Sehr verständlich und gut geschrieben!
    Meines Wissens unterbinden manche Hoster die Fehlerausgabe via .htaccess, das könnte man noch erwähnen ;)

  4. DerLeser 21. Februar 2009 at 00:48 #

    Vielleicht sollte man noch erwähnen, dass PHP-Fehlermeldungen schon deshalb im Produktivbetrieb vor dem Besucher verborgen werden sollten, weil die dabei ausgegebenen Pfadangaben in dem einen oder anderen Fall durchaus ein Sicherheitsrisiko darstellen können.

  5. Ongimann 21. Februar 2009 at 07:39 #

    Mit php_value error_reporting 2047 in der .htaccess kann man ja alle fehler anzeigen. Aber wie kann man denn per .htaccess die Anzeige aller fehler unterdrücken?

  6. rasmus 21. Februar 2009 at 12:08 #

    zwar keine große neuikeit, aber dabke für die komplette und nützliche übersicht.

  7. Marcel 22. Februar 2009 at 11:13 #

    Sehr nützliche Übersicht! Bin schon oft verzweifelt, weil ich die php ini auf meinem Webspace nie dies bzgl. anpassen konnte…

  8. Daniel Brito Mendes 22. Februar 2009 at 20:59 #

    Sehr schön ist die Fehler in einer logdatei zu haben.
    So kann man später besser analysieren.

  9. Simon 27. Februar 2009 at 23:12 #

    Hi,

    die Übersicht ist wirklich sehr gelungen.
    Ich habe in der Entwicklung die error_reporting-Einstellung auch immer auf E_ALL bzw. E_ALL | E_STRICT

    Simon

  10. Webmaster 5. März 2009 at 11:48 #

    Kleiner Tipp: ich handle meine Fehler alle in einer error.php, damit das nur an einer Stelle passiert.

    Außerdem lohnt sich ein Blick “Exceptions”. ;)

  11. Walter 16. Januar 2010 at 23:10 #

    Man darf als Entwickler nicht vergessen das auch sehr unbedarfte Benutzer die Seite benutzen.
    Grundregel: Es gibt keine bugfreie Software.
    Also, wie geht man mit fehlern um?
    Man versucht ihn vorm Kunden zu vertuschen, Meldung an den Admin aber bitte keine ausführlichen meldungen an den benutzer.

    Viel interessanter ist es den Kunden trotz des Fehlers an die Seite zu binden.
    Leider ist nicht jeder Programmierer kreativ.

    Trotz allem, ein wichtiger Beitrag von Dr.Web

Trackbacks

  1. Netzor.de - Blog.netzor.de - Webmastering, Linux und freie Software. >> Eine Schippe nützlicher Links - Teil 2 - 31. Juli 2009

    [...] Interne Fehlerbehandlung von PHP [...]

Hinterlasse eine Antwort

Bitte bei weiteren Kommentaren per Email benarichtigen! Auch möglich: Abo ohne Kommentar.

Spam protection by WP Captcha-Free