Fehler:
Wenn PHP etwas tun soll, was es nicht kann, tritt ein Fehler auf. Tritt ein Fehler auf, bricht der PHP-Interpreter (je nach Schwere) das Script ab und/oder gibt eine Meldung aus. Hier beschreibe ich unterschiedliche Fehlermeldungen, wie deren Anzeige unterdrückt werden kann und was stattdessen zu tun ist.
Fehlermeldungen in PHP
Stösst der PHP-Parser auf einen Fehler im Code gibt er im Browser eine recht hässliche aber wärend des Programmierens sehr hilfreiche Fehlermeldung aus. Eine solche Meldung wirkt aber in einer fertigen Site sehr unprofessionell und gibt einem Bösewicht noch unerwünscht Informationen, welche ihm helfen, weshalb nach dem Programmieren und Testen die Fehlermeldungen auf dem produktiven Server ausgeschaltet werden sollen (siehe php.ini).
Es gibt etliche Fehlerlevel mit ihren Meldungen:
- E_NOTICE
Die Ausführung des Script wird nicht abgebrochen, das Script funktioniert wahrscheinlich dennoch. - E_WARNING
Die Ausführung des Script wird vielleicht abgebrochen, das Script funktioniert jedoch sicher nicht. - E_PARSE Syntaxfehler (z.B. ; vergessen)
Die Ausführung des Script wird abgebrochen, das Script funktioniert nicht. - E_ERROR Fatal error
Die Ausführung des Script wird sicher abgebrochen. - E_STRICT neu in PHP 5, Script funktioniert wegen Rückwärtskompatibilität von PHP dennoch.
Meldet z.B. wenn Eigenschaften in einer Klasse mit 'var' (aus PHP 4) statt mit 'public' (neu in PHP 5) deklariert wurden. - E_RECOVERABLE_ERROR neu in PHP 5.2 für fatale Fehler, welche aber mit eigenen Fehlerhandlern via 'set_error_handler() abgefangen werden können.
- E_DEPRECATED bei Verwendung veralteter Methoden wie 'preg_replace()' in PHP 5.3.
Auf der folgenden Seite beschreibe ich meine häuffigsten Anfängerfehler beim Programmieren
anhand der generierten Fehlermeldungen und was ich dagegen getan habe:
errors_dr.php
Fehler anzeigen oder Anzeige unterdrücken
php.ini
Wird die Fehleranzeige unterdrückt, ist der Fehler damit nicht behoben.
Ob und welche Fehler angezeigt werden, ist in der php.ini Datei festgelegt.
Es gibt Hosts, die erlauben das Ändern dieser Datei. (Zuhause auf dem Testserver
sollte ich die Ausgabe der Fehlermeldung natürlich nicht unterdrücken.)
Aber Achtung: Fatale Fehler, auch wenn keine Meldung ausgegeben wird,
führen gleichwohl zum Abbruch des Scripts!
Die relevanten Einträge zum Anzeigen/Unterdrücken von Fehlermeldungen in der php.ini
sind folgende:
error_reporting = E_ALL display_errors = Off log_errors = On error_log = ... (Pfadangabe zum Speicherort der Logdatei)
php.ini zur Laufzeit umgehen
Ich kann die Fehlerausgabe im Browser ausschalten, auch wenn sie in php.ini angeschaltet ist.
Falls ich keinen Zugriff auf die Datei php.ini auf dem Server habe, dann kann ich zur Laufzeit meines Scripts die Anzeige der Fehlermeldungen wie folgt konfigurieren! (Konfigurieren heisst: ich kann nicht nur gewisse Meldungen verhindern, ich kann auch gewisse Meldungen erlauben, unbesehen davon, wie die php.ini-Datei dies vorsieht (der Server-Administrator kann natürlich alles und jedes in seiner httpd.conf ausschliessen oder gewähren). )
ini_set() und error_reporting()
Alle Fehler anzeigen:
ini_set('display_errors', 1); // 0 ist alles off
Nur Laufzeitfehler ausgeben und Warnungen:
error_reporting(E_ERROR | E_WARNING);
das verbindende und wird durch die | (Pipe) angegeben
Alle Fehlermeldungen anzeigen ausser den Notices:
error_reporting(E_ALL ^ E_NOTICE);
das ausser wird als ^ (Dach) oder ~ (Tilde) geschrieben
Strikte Fehlermeldungen anzeigen:
error_reporting(E_ALL | E_STRICT);
Alle Fehler und noch die neue Variante
Stict dazu anzeigen, welche auch die Verwendung veralteter (deprecated) Funktionen meldet.
Einstellung via .htaccess
.htaccess
Falls der Apache-Server Administrator dies durch 'AllowOverride' in der httpd.conf zulässt:
In einer separaten Datei, welche als .htaccess benannt ist, schreibe ich folgende Zeile.
php_admin_flag display_errors 0
Diese Einstellung gilt für das Verhalten des Ordners, in dem diese Datei liegt,
mit allen seinen Unterordnern.
Mehr in .ht-Dateien
Fehlerausgabe durch @ unterdrücken
@funktion()
$datei=@fopen("datei.txt");
Funktionen, die beispielsweise mit externen Dateien arbeiten, geben eine Fehlermeldung aus, wenn diese Datei nicht gefunden wird. Jede Meldung kann unterdrückt werden durch das Voranstellen des Zeichens @ vor den Funktionsaufruf. Das Script wird jedoch weiter verarbeitet und Folgefehler treten auf, diese sind kaum zu lokalisieren, mitunter wird einfach eine leere Seite präsetiert.
Fehlermeldung generieren
or die()
or die("Meine persönliche Fehlermeldung"); gibt Fehlermeldung aus:
$datei=fopen("datei.txt") or die("Diese Seite steht
im Moment nicht zur Verfügung.");
Es ist natürlich zu bedenken, ob es sinnvoll ist, einem Einbrecher, allzugenaue Hinweise zu geben, welche Fehler er begangen hat oder welche Massnahmen ich ergriffen habe.
or exit()
$datei=fopen("datei.txt") or exit();
Die Fehlermeldung wird unterdrückt (falls ich keine als String in die Klammer schreibe), das Script wird einfach abgebrochen und es wird unter Umständen (Fatal Error) eine leere Seite präsetiert, darum sollten Fehler aufgefangen werden und das Script entsprechend fortgesetzt werden.
Letzter Fehler speichern
$php_errormsg
Die zuletzt generierte PHP Fehlermeldung wird in der PHP Variablen $php_errormsg
gespeichert
(nur in dem Sript wo der Fehler auftrat kann auf diese Variable zugegriffen werden)
und nur wenn in der php.ini Datei der Eintrag track_error = True ist.
echo "<strong>Letzte Fehlermeldung:</strong> $php_errormsg<br />\n";
Letzter Fehler in MySQL
mysql_error()
PHP gibt bei MySQL-Fehlern nur bei schweren Datenbankfehlern eine Fehlermeldung aus, unterdrückt aber fehlgeschlagene Lese- und Schreibzugriffe (mit SELECT, INSERT und UPDATE) aus Sicherheitsgründen, um Angreiffern keine Hinweise zu geben. Stattdessen speichert PHP die Fehlermeldung des MySQL-Servers; durch die Funktion mysql_error() lässt sich der jeweils letzte Fehler innerhalb des Scripts noch aufrufen:
$doit = mysql_query($query) or die(mysql_error());
oder:
$fehler = mysql_error(); if(!empty($fehler)) { echo "MYSQL Fehler: ".$fehler; } else { echo "MYSQL erfolgreich"; }
oder:
if (!doit) { $status = mysql_error(); } else { $status = "OK"; } echo $status;
Fehler-LOG
Der Funktion error_log() kann ein Wert 0-3 mitgegeben werden:
0 schreibt einen String in die (in der php.ini vielleicht definierten) Logdatei
(siehe oben bei error_log ...)
1 sendet eine E-Mail (siehe unten)
2 bemüht den PHP Debugger
3 schreibt einen String in eine beliebige Datei:
function mysqlfehler() { $fehler = date("Y-m-d | H:is | ") .mysql_error() .chr(13).chr(10) ."---------------------------------------" .chr(13).chr(10); error_log($fehler, 3, "mysqlfehler.txt"); }
Anfrage: $doit = @mysql_query($query) or mysqlfehler();
Jedenfalls bringt es dem Webmaster einiges, wenn er auftretende Fehler in
eine Logdatei schreibt und diese periodisch anschaut.
Lesen Sie zum Logwriter: log.php
E_Mail
Zumindest eine Nachricht an mich könnte ich per E-Mail senden:
$mail = "mysqlfehler@biefer.com"; error_log($fehler,1,$mail);
Sicherheit
Grunssätzliche Überlegungen zur Sicherheit von Formulareingaben vor dem Übernehmen in Datenbank abfragen gibt es in der Datei sicherheit.php