PHP : Benutzerdefinierte Fehlerbehandlungsroutine – Umgang mit Parsing- und schwerwiegenden Fehlern

Lesezeit: 12 Minuten

Wie kann ich umgehen analysieren & tödlich Fehler mit a Benutzerdefiniert Fehlerbehandler?

  • Warum nicht Parse-Fehler im Upstream mit a abfangen php -l?

    – Milo LaMar

    25. Dezember 2018 um 23:36 Uhr

  • Wie machen Sie das von einem Browser aus, der ein PHP-Programm ausführt?

    – David Spector

    26. Juni 2021 um 11:44 Uhr

PHP Benutzerdefinierte Fehlerbehandlungsroutine Umgang mit Parsing und schwerwiegenden
jdias

Tatsächlich können Sie mit Parsing- und schwerwiegenden Fehlern umgehen. Die Fehlerbehandlungsfunktion, die Sie mit set_error_handler() definiert haben, wird zwar nicht aufgerufen. Dazu definieren Sie mit register_shutdown_function() eine Shutdown-Funktion. Hier ist, was ich in meiner Website arbeite:

Datei voranstellen.php (Diese Datei wird automatisch allen PHP-Skripten vorangestellt). Unten finden Sie Tipps zum Voranstellen von Dateien in 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 ruft die Funktion errorHandler() auf, wenn er einen Fehler in einem der Skripte feststellt. Wenn der Fehler das sofortige Herunterfahren des Skripts erzwingt, wird der Fehler von der Funktion shutdownHandler() behandelt.

Dies funktioniert auf der Website, die ich in der Entwicklung habe. In der Produktion habe ich es noch nicht getestet. Aber es fängt derzeit alle Fehler ab, die ich während der Entwicklung finde.

Ich glaube, es besteht die Gefahr, dass derselbe Fehler zweimal abgefangen wird, einmal von jeder Funktion. Dies könnte passieren, wenn ein Fehler, den ich in der Funktion shutdownHandler() behandle, auch von der Funktion errorHandler() abgefangen wurde.

TODOs:

1 – Ich muss an einer besseren log()-Funktion arbeiten, um Fehler elegant zu behandeln. Da ich mich noch in der Entwicklung befinde, protokolliere ich den Fehler im Grunde in einer Datenbank und gebe ihn auf dem Bildschirm wieder.

2 – Fehlerbehandlung für alle MySQL-Aufrufe implementieren.

3 – Fehlerbehandlung für meinen Javascript-Code implementieren.

WICHTIGE NOTIZEN:

1 – Ich verwende die folgende Zeile in meiner php.ini, um das obige Skript automatisch allen PHP-Skripten voranzustellen:

auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"

Es funktioniert gut.

2 – Ich protokolliere und behebe alle Fehler, einschließlich E_STRICT-Fehler. Ich glaube an die Entwicklung eines sauberen Codes. Während der Entwicklung hat meine php.ini-Datei die folgenden Zeilen:

track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0

Wenn ich live gehe, werde ich display_errors auf 0 ändern, um das Risiko zu verringern, dass meine Benutzer hässliche PHP-Fehlermeldungen sehen.

Ich hoffe, das hilft jemandem.

  • Scheint “Parse Errors” nicht zu verarbeiten… versuchen Sie Folgendes: echo “Cat”; echo “Hund” echo “Löwe”;

    – Phantom007

    10. Mai 2014 um 17:56 Uhr


  • Sie müssen die Datei voranstellen, um Parsing-Fehler zu behandeln!

    – dargmüesli

    24. Oktober 2016 um 16:22 Uhr

  • E_DEPRECATED und E_USER_DEPRECATED sollte auch in der benutzerdefinierten Fehlerbehandlungsfunktion enthalten sein.

    – Wh1T3h4Ck5

    19. September 2017 um 3:38 Uhr

  • Wenn ich eine Datei wie diese manuell voranstelle, wird der Fehler “abc();” nicht abgefangen, bei dem abc nicht definiert ist. Der Fehler “nicht behandelt” wird angezeigt. Bitte geben Sie ein vollständiges Testbeispiel an.

    – David Spector

    31. Januar 2020 um 19:16 Uhr

PHP Benutzerdefinierte Fehlerbehandlungsroutine Umgang mit Parsing und schwerwiegenden
Dan Seife

Einfache Antwort: Sie können nicht. Siehe die Handbuch:

Die folgenden Fehlertypen können nicht mit einer benutzerdefinierten Funktion behandelt werden: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING und die meisten von E_STRICT, die in der Datei ausgelöst werden, in der set_error_handler() aufgerufen wird.

Für jeden anderen Fehler können Sie verwenden set_error_handler()

BEARBEITEN:

Da es anscheinend einige Diskussionen zu diesem Thema gibt, in Bezug auf die Verwendung register_shutdown_functionsollten wir einen Blick auf die Definition von Handling werfen: Einen Fehler zu behandeln bedeutet für mich, den Fehler abzufangen und auf eine Weise zu reagieren, die für den Benutzer „nett“ ist und die zugrunde liegenden Daten (Datenbanken, Dateien, Webservices etc.).

Verwenden register_shutdown_function Sie können einen Fehler nicht innerhalb des Codes behandeln, in dem er aufgerufen wurde, was bedeutet, dass der Code an der Stelle, an der der Fehler auftritt, immer noch nicht mehr funktioniert. Sie können dem Benutzer jedoch eine Fehlermeldung anstelle einer weißen Seite präsentieren, aber Sie können beispielsweise nichts rückgängig machen, was Ihr Code vor dem Fehlschlagen getan hat.

  • Tatsächlich können Sie diese Fehler mit einer benutzerdefinierten Funktion behandeln. Sie müssen lediglich register_shutdown_function definieren. Siehe meine Antwort unten für ein funktionierendes Beispiel, das ich auf meiner Website implementiert habe.

    – jdias

    20. September 2011 um 18:32 Uhr

  • Ja, du kannst. Es gibt jedoch einige Nachteile: siehe meine Bearbeitung oben

    – Dan Seife

    30. September 2011 um 20:59 Uhr

  • Danke für das Update. Eigentlich können Sie mehr tun, als dem Benutzer eine Fehlermeldung zu präsentieren. Sie können die Details des Fehlers protokollieren, einschließlich Variablen, die zum Zeitpunkt des Auftretens des Fehlers festgelegt wurden. Viele Leute, die Shared Hosting verwenden, haben beispielsweise keinen Zugriff auf Apache-Protokolle. Durch die Verwendung dieser Funktion könnten sie kritische Fehler protokollieren und beheben. Darüber hinaus können Sie versuchen, Transaktionen wiederherzustellen. Wenn der Fehler beispielsweise aufgetreten ist, als der Benutzer versucht hat, eine Bestellung aufzugeben, können Sie alle Details der Bestellung in einem Protokoll oder einer E-Mail speichern und versuchen, sie offline wiederherzustellen.

    – jdias

    30. September 2011 um 21:50 Uhr

  • Oder Sie können sie über eine App wie NewRelic „handhaben“, mit der Sie sie erfassen und dann proaktiv überwachen und beheben können. Wenn Sie sie einfach ignorieren, werden sie nie bearbeitet.

    – GL_Stephen

    31. März 2014 um 18:30 Uhr

  • Wie in den anderen Antworten erwähnt, können Sie fangen alle Art der Fehler von includes (nicht: require). Sie brauchen also nur eine kleine obere Ebene .php Datei, die das ganze Fangen macht, was dann includeist der echte. Das lässt sich relativ einfach umsetzen NginX und php-fpm (Hinweis: cgi.fix_pathinfo=0).

    – Tine

    24. August 2017 um 16:25 Uhr

PHP Benutzerdefinierte Fehlerbehandlungsroutine Umgang mit Parsing und schwerwiegenden
Denis Koslows

Sie können diese Fehler mit folgendem Code nachverfolgen:

(Parse-Fehler können nur abgefangen werden, wenn sie in auftreten andere Skriptdateien über include() oder require()oder indem Sie diesen Code in eine einfügen auto_prepend_file wie andere Antworten erwähnt haben.)

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');

  • Ja, es gibt eine Möglichkeit, E_PARSE zu fangen! Fügen Sie die Fehlerbehandlungsfunktion in index.php ein und fügen Sie eine andere Datei hinzu, in der sich die Site-Logik befinden sollte!

    – Lukas Batistussi

    12. Mai 2012 um 21:59 Uhr

  • Die einzige Möglichkeit, die Anzeige von Parsing-Fehlern zu verhindern, bestand darin, das Skript einzuschließen, das den Parsing-Fehler enthielt.

    – Melsi

    27. April 2013 um 0:00 Uhr

  • @LucasBatistussi, Sie können immer noch keine Parsing-Fehler für index.php abfangen

    – Schrittmacher

    19. Juli 2013 um 18:00 Uhr


  • Testen auf PHP 5.3 – Win 7. Die Shutdown-Funktion wird bei Parsing-Fehlern NICHT aufgerufen.

    – Kwolfe

    17. September 2013 um 20:29 Uhr

  • @LucasBatistussi kannst du das erklären? Ich habe die Fehlerbehandlungsfunktion eingefügt index.php & fügen Sie es dann mit in mein Skript ein include(index.php). Aber es kann immer noch keine Analysefehler (Syntaxfehler) abfangen. Ich glaube nicht, dass es möglich ist, ohne es in php.ini einzubetten.

    – Khurshid Alam

    20. August 2014 um 18:31 Uhr

Aus den PHP.net-Kommentaren auf der Seite http://www.php.net/manual/en/function.set-error-handler.php

Mir ist aufgefallen, dass einige Leute hier erwähnt haben, dass Sie Parsing-Fehler nicht erfassen können (Typ 4, E_PARSE). Das ist nicht wahr. Hier ist, wie ich es mache. Ich hoffe, das hilft jemandem.

1) Erstellen Sie eine „auto_prepend.php“-Datei im Web-Root und fügen Sie diese hinzu:

<?php 
register_shutdown_function('error_alert'); 

function error_alert() 
{ 
        if(is_null($e = error_get_last()) === false) 
        { 
                mail('[email protected]', 'Error from auto_prepend', print_r($e, true)); 
        } 
} 
?> 

2) Fügen Sie dann diese „php_value auto_prepend_file /www/auto_prepend.php“ zu Ihrer .htaccess-Datei im Web-Root hinzu.

  • Stellen Sie sicher, dass Sie die E-Mail-Adresse und den Pfad zur Datei ändern.

1646604857 176 PHP Benutzerdefinierte Fehlerbehandlungsroutine Umgang mit Parsing und schwerwiegenden
Melsi

Meiner Erfahrung nach können Sie alle Arten von Fehlern abfangen, die Standardfehlermeldung ausblenden und eine eigene Fehlermeldung anzeigen (wenn Sie möchten). Nachfolgend sind die Dinge aufgeführt, die Sie benötigen.

1) Nennen wir es ein Initial-/Top-Level-Skript index.php wo Sie Ihre benutzerdefinierten Fehlerbehandlungsfunktionen speichern. Benutzerdefinierte Fehlerfunktionshandler müssen oben bleiben, damit sie Fehler darunter abfangen, mit “unten” meine ich in eingeschlossenen Dateien.

2) Die Annahme, dass dieses Top-Skript fehlerfrei ist, muss wahr sein! Dies ist sehr wichtig, Sie können keine schwerwiegenden Fehler einfangen index.php wenn Ihre benutzerdefinierte Fehlerbehandlungsfunktion in gefunden wird index.php.

3) Php-Direktiven (müssen auch in index.php)
set_error_handler("myNonFatalErrorHandler"); #um nicht schwerwiegende Fehler abzufangen
register_shutdown_function('myShutdown'); #um schwerwiegende Fehler abzufangen
ini_set('display_errors', false); #um Fehler zu verbergen, die dem Benutzer von PHP angezeigt werden
ini_set('log_errors',FALSE); #vorausgesetzt wir protokollieren die Fehler selbst
ini_set('error_reporting', E_ALL); #Wir melden gerne alle Fehler

Während der Produktion (wenn ich mich nicht irre) können wir gehen ini_set('error_reporting', E_ALL); wie es ist, um gleichzeitig Fehler protokollieren zu können ini_set('display_errors', false); stellt sicher, dass dem Benutzer keine Fehler angezeigt werden.

Was den eigentlichen Inhalt der beiden Funktionen betrifft, von denen ich spreche, myNonFatalErrorHandler und myShutdown, ich füge hier keinen detaillierten Inhalt hinzu, um die Dinge einfach zu halten. Darüber hinaus haben die anderen Besucher viele Beispiele gegeben. Ich zeige nur eine sehr einfache 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
}

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');

  • Vielen Dank für das Hinzufügen, dass sich die Funktionen nicht in derselben Datei wie der Fehler befinden können.

    – Nikolaus

    18. Dezember 2015 um 9:18 Uhr

  • Verwenden Sie besser eine Schließung als Fehlerbehandler, weil Benannte Funktionen können überschrieben werden heutzutage

    – Tine

    24. August 2017 um 16:16 Uhr

  • Dies ist die einzige Antwort, die für mich funktioniert. Der Schlüssel war ini_set('display_errors', false); um die PHP-Berichte auszublenden. Es sollte auch beachtet werden, dass die Funktion set_error_handler nicht benötigt wird, da der Callback register_shutdown_function sogar E_NOTICE-Fehler empfängt, wie z. B. die Verwendung von definierten Konstanten, die nicht definiert wurden. Mit diesem Verständnis ist eine Ausnahmebehandlung (Try/Catch) für viele Programme nicht erforderlich, die beim ersten erkannten Fehler anhalten.

    – David Spector

    31. Januar 2020 um 19:50 Uhr

1646604858 584 PHP Benutzerdefinierte Fehlerbehandlungsroutine Umgang mit Parsing und schwerwiegenden
Jan Turoň

Das Skript mit Parsing-Fehler wird immer unterbrochen und kann nicht behandelt werden. Wenn das Skript also direkt oder per include/require aufgerufen wird, können Sie nichts tun. Aber wenn es von AJAX, Flash oder auf andere Weise aufgerufen wird, gibt es ist eine Problemumgehung, wie Parsing-Fehler erkannt werden.

Ich musste damit umgehen swfupload Skript. Swfupload ist ein Flash, das Datei-Uploads verarbeitet und jedes Mal, wenn eine Datei hochgeladen wird, ruft es das PHP-Handling-Skript auf, um Dateidaten zu verarbeiten – aber es gibt keine Browserausgabe, daher benötigt das PHP-Handling-Skript diese Einstellungen für Debugging-Zwecke:

  • Warnungen und Hinweise ob_start(); am Anfang und Inhalt in Sitzung speichern durch ob_get_contents(); am Ende des Bearbeitungsskripts: Dies kann durch ein anderes Skript im Browser angezeigt werden
  • fatale Fehler register_shutdown_function(), um die Sitzung mit dem gleichen Trick wie oben festzulegen
  • Fehler analysieren wenn sich ob_get_contents() am Ende des Behandlungsskripts befindet und vorher ein Analysefehler aufgetreten ist, wird die Sitzung nicht gefüllt (sie ist null). Das Debugging-Skript kann dies folgendermaßen handhaben: if(!isset($_SESSION["swfupload"])) echo "parse error";

Anmerkung 1 null bedeutet is not set zu isset()

  • Vielen Dank für das Hinzufügen, dass sich die Funktionen nicht in derselben Datei wie der Fehler befinden können.

    – Nikolaus

    18. Dezember 2015 um 9:18 Uhr

  • Verwenden Sie besser eine Schließung als Fehlerbehandler, weil Benannte Funktionen können überschrieben werden heutzutage

    – Tine

    24. August 2017 um 16:16 Uhr

  • Dies ist die einzige Antwort, die für mich funktioniert. Der Schlüssel war ini_set('display_errors', false); um die PHP-Berichte auszublenden. Zu beachten ist auch, dass die set_error_handler-Funktion nicht benötigt wird, da der register_shutdown_function-Callback sogar E_NOTICE-Fehler entgegennimmt, wie z. B. die Verwendung definierter Konstanten, die nicht definiert wurden. Mit diesem Verständnis ist eine Ausnahmebehandlung (Try/Catch) für viele Programme nicht erforderlich, die beim ersten erkannten Fehler anhalten.

    – David Spector

    31. Januar 2020 um 19:50 Uhr

960190cookie-checkPHP : Benutzerdefinierte Fehlerbehandlungsroutine – Umgang mit Parsing- und schwerwiegenden Fehlern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy