PHP: Benutzerdefinierte Fehlerbehandlung - Umgang mit Parse & fatale Fehler
-
19-09-2019 - |
Frage
Wie kann ich umgehen Parse & fatal Fehler mit einem benutzerdefinierte Fehlerbehandlung?
Lösung
Einfache Antwort: Sie können es nicht. Finden Sie in der Handbuch :
Die folgenden Fehlertypen können nicht sein mit einer benutzerdefinierten Funktion gehandhabt: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, und die meisten E_STRICT erhöhte in der Datei, in der set_error_handler () aufgerufen wird.
Für alle anderen Fehler, können Sie set_error_handler()
EDIT:
Da es scheint, dass es einige Diskussionen zu diesem Thema sind, in Bezug auf register_shutdown_function
verwenden, sollten wir einen Blick auf die Definition der Handhabung nehmen: Für mich, wird eine Fehlerverwaltungsmittel den Fehler zu kontrollieren und in einer Art und Weise reagieren, die ist "nett" für den Benutzer und die zugrunde liegenden Daten (Datenbanken, Dateien, Web-Service, usw.).
register_shutdown_function
verwenden Sie können einen Fehler nicht verarbeiten aus dem Code, in dem es hieß, würde den Code Sinn an der Stelle arbeiten noch stoppen, wo der Fehler auftritt. Sie können jedoch präsentieren den Benutzer eine Fehlermeldung statt einer weißen Seite, aber Sie können nicht zum Beispiel Rollback etwas, dass Ihr Code auf Fehler vor hat.
Andere Tipps
Eigentlich kann man Parse und fatale Fehler behandeln. Es ist wahr, dass die Fehler-Handler-Funktion Sie mit set_error_handler definiert () nicht aufgerufen werden. Die Möglichkeit, es zu tun, ist durch eine Abschaltfunktion mit register_shutdown_function definieren (). Hier ist, was ich in meiner Webseite arbeiten:
Datei prepend.php (diese Datei für alle PHP-Skripte vorangestellt werden automatisch). Siehe unten für Hinweise auf das Voranstellen von Dateien zu PHP.
set_error_handler("errorHandler");
register_shutdown_function("shutdownHandler");
function errorHandler($error_level, $error_message, $error_file, $error_line, $error_context)
{
$error = "lvl: " . $error_level . " | msg:" . $error_message . " | file:" . $error_file . " | ln:" . $error_line;
switch ($error_level) {
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_PARSE:
mylog($error, "fatal");
break;
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
mylog($error, "error");
break;
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_WARNING:
mylog($error, "warn");
break;
case E_NOTICE:
case E_USER_NOTICE:
mylog($error, "info");
break;
case E_STRICT:
mylog($error, "debug");
break;
default:
mylog($error, "warn");
}
}
function shutdownHandler() //will be called when php script ends.
{
$lasterror = error_get_last();
switch ($lasterror['type'])
{
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_PARSE:
$error = "[SHUTDOWN] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line'];
mylog($error, "fatal");
}
}
function mylog($error, $errlvl)
{
...do whatever you want...
}
PHP-Funktion errorhandler () aufrufen, wenn er einen Fehler in einem der Skripte fängt. Wenn die Fehlerkräfte zum Herunterfahren des Skript sofort, der Fehler durch die Funktion shutdownHandler gehandhabt wird ().
Dieses arbeitet an der Seite, die ich in der Entwicklung haben. Ich habe noch nicht in der Produktion getestet. Aber es ist zur Zeit alle Fehler zu kontrollieren finde ich, während es zu entwickeln.
Ich glaube, es besteht die Gefahr, den gleichen Fehler zu fangen zweimal, einmal durch jede Funktion. Dies könnte passieren, wenn ein Fehler, dass ich in der Funktion shutdownHandler () am Umgang wurde auch durch Funktion errorhandler gefangen ().
Todo:
1 - Ich muss die Arbeit an einem besseren log () Funktion Griff Fehler anmutig. Weil ich in der Entwicklung bin immer noch, ich bin die Anmeldung im Grunde um den Fehler zu einer Datenbank und halle es auf den Bildschirm an.
. 2 - Implementieren der Fehlerbehandlung für alle MySQL Anrufe
. 3 - Implementieren Fehler für meinen JavaScript-Code Handhabung
Wichtige Hinweise:
1 - Ich verwende die folgende Zeile in meiner php.ini, um automatisch das Skript für alle PHP-Skripte setzt:
auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"
es funktioniert gut.
2 - Ich bin Protokollierung und alle Fehler zu lösen, einschließlich E_STRICT Fehler. Ich glaube, einen sauberen Code zu entwickeln. Während der Entwicklung hat sich meine php.ini die folgenden Zeilen:
track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0
Wenn ich leben, ich werde display_errors auf 0 ändern, um die Gefahr meiner Benutzer sehen hässlich PHP-Fehlermeldungen zu reduzieren.
Ich hoffe, das jemand hilft.
Sie können diese Fehler verfolgen, wie dies mit dem Code:
(Parse-Fehler können nur gefangen werden, wenn sie auftreten, in andere Skriptdateien über include()
oder require()
oder durch diesen Code in ein auto_prepend_file
setzen, wie andere Antworten erwähnt.)
function shutdown() {
$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if ($isError){
var_dump ($error);//do whatever you need with it
}
}
register_shutdown_function('shutdown');
Von den PHP.net Kommentare auf der Seite http: / /www.php.net/manual/en/function.set-error-handler.php
Ich habe erkannt, dass ein paar Leute hier erwähnt, dass Sie nicht Parse-Fehler erfassen kann (Typ 4, E_PARSE). Das ist nicht wahr. Hier ist, wie ich es tue. Ich hoffe, das jemand hilft.
1) Erstellen Sie eine "auto_prepend.php" Datei im Web-Root und fügen Sie diese:
<?php
register_shutdown_function('error_alert');
function error_alert()
{
if(is_null($e = error_get_last()) === false)
{
mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true));
}
}
?>
2) Dann fügen Sie diesen „php_value auto_prepend_file /www/auto_prepend.php“auf Ihre .htaccess Datei im Web-Root.
- stellen Sie sicher, die E-Mail-Adresse ändern und den Pfad zur Datei.
Aus meiner Erfahrung kann man alle Arten von Fehlern fangen, blenden Sie die Fehlermeldung Standard und zeigt eine Fehlermeldung des eigenen (wenn Sie mögen). Nachfolgend sind die Dinge, die Sie benötigen.
1) Ein anfänglicher / Top-Level-Skript, nennen wir es index.php
, wo Sie Sie speichern benutzerdefinierte Handler-Funktionen Fehler. Benutzerdefinierte Fehlerfunktion Handler an der Spitze bleiben müssen, so dass sie Fehler unter ihnen fangen, von „unten“ ich in Inclued Dateien bedeuten.
2) Die Annahme, dass dieser Top-Skript muss fehlerfrei wahr sein! das ist sehr wichtig, man kann nicht fatale Fehler in index.php
fängt, wenn Ihre benutzerdefinierte Fehlerbehandlungsfunktion in index.php
gefunden wird.
3) Php-Richtlinien (muss auch in index.php
zu finden)
set_error_handler("myNonFatalErrorHandler");
#in um nicht-tödliche Fehler abzufangen
register_shutdown_function('myShutdown');
#in um schwerwiegende Fehler zu fangen
ini_set('display_errors', false);
#in um Fehler zu verstecken, um Benutzer von PHP gezeigt
ini_set('log_errors',FALSE);
#assuming wir die Fehler, uns selbst einzuloggen
ini_set('error_reporting', E_ALL);
#Wir wie alle Fehler melden
, während in der Produktion (wenn ich mich nicht irre) können wir ini_set('error_reporting', E_ALL);
verlassen, wie, um in der Lage sein, Fehler zu protokollieren, in der gleichen Zeit ini_set('display_errors', false);
werden dafür Sorge tragen, dass keine Fehler an den Benutzer angezeigt werden.
Wie für den eigentlichen Inhalt der beiden Funktionen ich spreche, myNonFatalErrorHandler
und myShutdown
, ich setzte nicht Inhalt hier detailliert, um die Dinge einfach zu halten. Darüber hinaus haben sich die anderen Besucher eine Menge Beispiele. Ich zeige nur eine sehr ebene Idee.
function myNonFatalErrorHandler($v, $m, $f, $l, $c){
$some_logging_var_arr1[]="format $v, $m, $f, ".$err_lvl[$l].", $c the way you like";
//You can display the content of $some_logging_var_arr1 at the end of execution too.
}
function myShutdown()
{
if( ($e=error_get_last())!==null ){
$some_logging_var_arr2= "Format the way you like:". $err_level[$e['type']].$e['message'].$e['file'].$e['line'];
}
//display $some_logging_var_arr2 now or later, e.g. from a custom session close function
}
wie für $ err_lvl kann es sein:
$err_lvl = array(E_ERROR=>'E_ERROR', E_CORE_ERROR=>'E_CORE_ERROR', E_COMPILE_ERROR=>'E_COMPILE_ERROR', E_USER_ERROR=>'E_USER_ERROR', E_PARSE=>'E_PARSE', E_RECOVERABLE_ERROR=>'E_RECOVERABLE_ERROR', E_WARNING=>'E_WARNING', E_CORE_WARNING=>'E_CORE_WARNING', E_COMPILE_WARNING=>'E_COMPILE_WARNING',
E_USER_WARNING=>'E_USER_WARNING', E_NOTICE=>'E_NOTICE', E_USER_NOTICE=>'E_USER_NOTICE',E_STRICT=>'E_STRICT');
Das Skript mit Parse-Fehler ist immer unterbrochen und es kann nicht behandelt werden. Also, wenn das Skript aufgerufen wird direkt oder durch include / erfordern, gibt es nichts, was man tun kann. Aber wenn es durch AJAX, Flash-Speicher oder auf andere Weise aufgerufen wird, gibt eine Abhilfe, wie Parse-Fehler zu erkennen.
Ich brauchte diese swfupload Skript zu behandeln. Swfupload ist ein Flash dass Griffe Datei-Uploads und jedes Mal die Dateien hochgeladen wird, ruft es Skript handle FILEDATA PHP Handling - aber es gibt keinen Browser ausgegeben, so dass die PHP Umgang Skript diese Einstellungen für Debugging-Zwecke benötigt:
- Warnungen und Hinweise ob_start (); am Anfang und Speicherinhalt in der Sitzung durch ob_get_contents (); am Ende des Handhabungs Skript: Der von einem anderen Skript in Browser angezeigt werden kann
- fatale Fehler register_shutdown_function () die Sitzung mit dem gleichen Trick wie oben einstellen
- Parse-Fehler , wenn die ob_get_contents () am Ende des Skripts Handhabung befindet und Parse-Fehler ist aufgetreten, bevor die Sitzung nicht gefüllt ist (es ist null). Der Debug-Skript kann es auf diese Weise handhaben:
if(!isset($_SESSION["swfupload"])) echo "parse error";
Hinweis 1 null
Mittel is not set
zu isset()