Menu

PHP Fehler anzeigen: error_reporting und display_errors

Um alle PHP-Fehler anzuzeigen, schreib ini_set('display_errors', '1'); und error_reporting(E_ALL); an den Anfang des Skripts oder setze display_errors = On und error_reporting = E_ALL in der php.ini. In Produktion Fehler protokollieren statt anzeigen.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Um PHP-Fehler anzuzeigen, schreib diese Zeilen an den Anfang deines Skripts: ini_set('display_errors', '1'); und error_reporting(E_ALL);. Die erste sorgt dafür, dass PHP Fehlermeldungen ausgibt, die zweite, dass es jede Art von Fehler meldet, auch Warnungen und Deprecations.

<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

Damit gibt ein Fehler, etwa das Lesen einer nie gesetzten Variable, eine Meldung mit Datei und Zeilennummer aus, statt still zu scheitern:

Warning: Undefined variable $total in /home/index.php on line 7

error_reporting() ohne Argument liefert die aktuelle Einstellung als Zahl. Klicke auf Run, um eine Stufe zu setzen und sie wieder in Namen zu übersetzen:

Jeder Fehlertyp ist ein Bit, deshalb bedeutet E_ALL & ~E_DEPRECATED „alles außer Deprecations“. Ändere die erste Zeile in error_reporting(E_ERROR | E_WARNING); und führe den Code erneut aus.

Fehler in der php.ini anzeigen

Eine Einstellung im Skript gilt erst, sobald das Skript läuft. Um Fehler für jedes Skript anzuzeigen, auch Parse-Fehler, änderst du die php.ini (finde sie mit php --ini):

; Development
display_errors = On
display_startup_errors = On
error_reporting = E_ALL

Starte Apache oder PHP-FPM nach dem Bearbeiten neu. Der eingebaute Server php -S und die Kommandozeile lesen die Datei bei jedem Start. Auf Shared Hosting ohne Zugriff auf die php.ini akzeptiert Apache mit mod_php auch Zeilen in der .htaccess:

php_flag display_errors on
php_value error_reporting -1

-1 setzt jedes Bit und ist damit dasselbe wie E_ALL.

Die Fehlerstufen

KonstanteWas sie auslöstStoppt das Skript
E_ERRORFataler Laufzeitfehler, etwa wenn der Speicher ausgehtja
E_PARSESyntaxfehler in der Dateija
E_WARNINGUndefinierte Variable oder undefinierter Array-Schlüssel, fehlende Datei bei includenein
E_NOTICEKleinere Probleme (in PHP 8 gibt es nur noch wenige)nein
E_DEPRECATEDCode, den eine zukünftige PHP-Version ablehnen wirdnein
E_USER_*Fehler, die du mit trigger_error() auslöstnur E_USER_ERROR
E_ALLJede Stufe, auch Core- und Compile-Fehler, die hier nicht aufgeführt sind

PHP 8.0 hat viele alte Warnungen in Exceptions umgewandelt: Division durch null mit / und die Übergabe eines falschen Typs an eine eingebaute Funktion werfen jetzt eine Unterklasse von Error, so wie es der Aufruf einer undefinierten Funktion seit PHP 7 tut. Alle drei kannst du abfangen:

Exceptions werden unter try und catch behandelt. Warnungen, Notices und Deprecations laufen weiterhin über das hier beschriebene Fehlersystem.

Fehler protokollieren statt anzeigen

Auf einer Live-Website sollten Besucher nie Fehlermeldungen sehen: Sie verraten Pfade, SQL und Code. Schreib sie stattdessen in eine Logdatei:

; Production
display_errors = Off
log_errors = On
error_log = /var/log/php/app-errors.log
error_reporting = E_ALL

Behalte error_reporting = E_ALL auch in Produktion. Wenn du es herunterdrehst, verschwinden die Fehler nicht, du erfährst nur nichts mehr davon. Eigene Meldungen können mit error_log() ins selbe Log gehen:

<?php
error_log("Payment failed for order 1042");

Beobachte die Datei dann beim Testen: tail -f /var/log/php/app-errors.log.

Warnungen mit set_error_handler in Exceptions umwandeln

set_error_handler ersetzt die Standardbehandlung von Warnungen, Notices und Deprecations durch deine eigene Funktion. Ein gängiges Muster wandelt jede davon in eine ErrorException um, sodass ein vergessener Array-Schlüssel den Code wie jede andere Exception stoppt und abgefangen werden kann:

Der Handler bekommt die Fehlerstufe als erstes Argument und kann Stufen deshalb unterschiedlich behandeln. Dieser hier protokolliert nur Deprecations und macht aus allem anderen eine Exception:

Fatale Fehler und Parse-Fehler erreichen den Handler nie, weil das Skript danach nicht weiterlaufen kann. Um sie aufzuzeichnen, registrierst du eine Shutdown-Funktion, die error_get_last() ausliest.

Den letzten Fehler mit error_get_last lesen

Manche Funktionen geben false zurück und melden den Grund nur als Warnung, zum Beispiel file_get_contents bei einer fehlenden Datei. error_get_last() liefert diese Warnung als Array. Das ist praktisch, wenn du eine eigene Meldung anzeigen willst:

Der Operator @ vor dem Aufruf unterdrückt die Meldung für genau diesen einen Ausdruck. Setze ihn sparsam ein und nur, wenn du das Ergebnis direkt danach prüfst, wie hier; ein @ allein versteckt nur Bugs.

Typischer Fehler: Fehlerausgabe ist an, aber die Seite bleibt leer

Wenn du ini_set('display_errors', '1') eingefügt hast und trotzdem eine weiße Seite siehst, ist der Fehler wahrscheinlich ein Parse-Fehler. PHP parst die ganze Datei, bevor die erste Zeile läuft, also stoppt ein fehlendes ; oder } alles, bevor ini_set ausgeführt wird. Prüfe die Datei im Terminal, das die Meldung immer ausgibt:

php -l index.php
Errors parsing index.php
PHP Parse error:  syntax error, unexpected token "," in index.php on line 2

Die Zeilennummer zeigt, wo PHP aufgegeben hat, und das ist oft die Zeile nach dem eigentlichen Fehler. Behebe ihn, führe php -l erneut aus, bis No syntax errors detected erscheint, und lade dann die Seite neu.

Häufig gestellte Fragen

Wie zeige ich alle Fehler in PHP an?

Schreib ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); ganz an den Anfang des Skripts oder setze display_errors = On und error_reporting = E_ALL in der php.ini und starte den Webserver oder PHP-FPM neu.

Warum zeigt meine PHP-Seite nur eine weiße Seite?

Ein fataler Fehler hat das Skript beendet, während display_errors aus ist, also wurde nichts ausgegeben. Schalte die Fehlerausgabe ein (oder lies das Fehlerlog, zum Beispiel mit tail -f auf die Datei, auf die error_log zeigt), um die Meldung und die Zeilennummer zu sehen.

Warum zeigt ini_set('display_errors', 1) meinen Parse-Fehler nicht an?

Ein Parse-Fehler stoppt PHP, bevor auch nur eine Zeile der Datei läuft, also wird der Aufruf von ini_set nie ausgeführt. Setze display_errors in der php.ini oder schreib das ini_set in eine kleine Datei, die dann die fehlerhafte per include einbindet.

Sollte display_errors in Produktion eingeschaltet sein?

Nein. Fehlermeldungen verraten Besuchern Dateipfade und Details zum Code. In Produktion verwendest du display_errors = Off, log_errors = On und einen Pfad für error_log und behältst error_reporting = E_ALL, damit Probleme trotzdem aufgezeichnet werden.

Was macht error_reporting(0)?

Es schaltet die Meldung aller Fehlertypen für den Rest des Skripts ab, sodass Warnungen und sogar fatale Fehler keine Meldung erzeugen. Das versteckt Probleme, statt sie zu beheben; protokolliere Fehler lieber, statt sie stummzuschalten.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S