Ich kann die set_error_handler()
meisten PHP-Fehler abfangen, aber es funktioniert nicht bei schwerwiegenden ( E_ERROR
) Fehlern, z. B. beim Aufrufen einer nicht vorhandenen Funktion. Gibt es eine andere Möglichkeit, diese Fehler abzufangen?
Ich versuche, mail()
alle Fehler abzurufen und verwende PHP 5.2.3.
php
fatal-error
zu viel php
quelle
quelle
Antworten:
Protokollieren Sie schwerwiegende Fehler mit dem
register_shutdown_function
, für das PHP 5.2+ erforderlich ist:Sie müssen die
error_mail
undformat_error
Funktionen definieren . Zum Beispiel:Verwenden Sie Swift Mailer , um die
error_mail
Funktion zu schreiben .Siehe auch:
quelle
mail("[email protected]", "My Site: FATAL ERROR", "Details: " . $errno . ' ' . $errstr . ' ' . $errfile . ' ' . $errline);
Ich habe mir gerade diese Lösung ausgedacht (PHP 5.2.0+):
Bei vordefinierten Konstanten werden verschiedene Fehlertypen definiert .
quelle
If an error handler (see set_error_handler ) successfully handles an error then that error will not be reported by this function.
"register_shutdown_function()
muss früher erfolgen als jeder schwerwiegende Fehler.use_1T_memory(); /* memory exhausted error here! */ register_shutdown_function('shutDownFunction');
funktioniert nicht wie erwartet.PHP bietet keine herkömmlichen Mittel zum Abfangen und Wiederherstellen schwerwiegender Fehler. Dies liegt daran, dass die Verarbeitung normalerweise nach einem schwerwiegenden Fehler nicht wiederhergestellt werden sollte. Ein String, der einem Ausgabepuffer entspricht (wie im ursprünglichen Beitrag der auf PHP.net beschriebenen Technik vorgeschlagen), ist definitiv nicht ratsam. Es ist einfach unzuverlässig.
Das Aufrufen der Funktion mail () innerhalb einer Fehlerbehandlungsmethode erweist sich ebenfalls als problematisch. Wenn Sie viele Fehler hätten, wäre Ihr Mailserver mit Arbeit geladen, und Sie könnten sich in einem knorrigen Posteingang befinden. Um dies zu vermeiden, können Sie einen Cron ausführen, um Fehlerprotokolle regelmäßig zu scannen und entsprechende Benachrichtigungen zu senden. Vielleicht möchten Sie sich auch mit Systemüberwachungssoftware wie Nagios befassen .
Um mit dem Bit über das Registrieren einer Abschaltfunktion zu sprechen:
Es ist wahr, dass Sie eine Abschaltfunktion registrieren können, und das ist eine gute Antwort.
Der Punkt hier ist, dass wir normalerweise nicht versuchen sollten, schwerwiegende Fehler zu beheben, insbesondere nicht, indem wir einen regulären Ausdruck für Ihren Ausgabepuffer verwenden. Ich antwortete auf die akzeptierte Antwort , die mit einem Vorschlag auf php.net verknüpft war, der inzwischen geändert oder entfernt wurde.
Dieser Vorschlag bestand darin, während der Ausnahmebehandlung einen regulären Ausdruck für den Ausgabepuffer zu verwenden und im Falle eines schwerwiegenden Fehlers (der durch den Abgleich mit dem möglicherweise erwarteten konfigurierten Fehlertext erkannt wird) eine Wiederherstellung oder eine fortgesetzte Verarbeitung durchzuführen. Das wäre keine empfohlene Vorgehensweise (ich glaube, deshalb kann ich auch den ursprünglichen Vorschlag nicht finden. Ich übersehen ihn entweder oder die PHP-Community hat ihn abgeschossen).
Es kann erwähnenswert sein, dass die neueren Versionen von PHP (um 5.1) die Abschaltfunktion früher aufzurufen scheinen, bevor der Rückruf für die Ausgabepufferung aufgerufen wird. In Version 5 und früheren Versionen war diese Reihenfolge umgekehrt (auf den Rückruf der Ausgabepufferung folgte die Funktion zum Herunterfahren). Seit ungefähr 5.0.5 (das ist viel früher als die Version 5.2.3 des Fragestellers) werden Objekte lange vor dem Aufruf einer registrierten Abschaltfunktion entladen, sodass Sie sich nicht auf Ihre In-Memory-Objekte verlassen können viel von allem.
Das Registrieren einer Abschaltfunktion ist also in Ordnung, aber die Art von Aufgaben, die von einer Abschaltfunktion ausgeführt werden sollten, sind wahrscheinlich auf eine Handvoll sanfter Abschaltvorgänge beschränkt.
Der Schlüssel zum Mitnehmen sind hier nur einige Worte der Weisheit für jeden, der über diese Frage stolpert und den Rat in der ursprünglich akzeptierten Antwort sieht. Regexen Sie Ihren Ausgabepuffer nicht neu.
quelle
Nun, es scheint möglich zu sein, schwerwiegende Fehler auf andere Weise zu erkennen :)
quelle
Schwerwiegende Fehler oder behebbare schwerwiegende Fehler lösen jetzt Instanzen von
Error
in PHP 7 oder höheren Versionen aus . Wie alle anderen Ausnahmen könnenError
Objekte mit a gefangen werdentry/catch
Block .Beispiel:
https://3v4l.org/67vbk
Oder Sie können die
Throwable
Schnittstelle verwenden, um alle Ausnahmen abzufangen.Beispiel:
https://3v4l.org/Br0MG
Für weitere Informationen: http://php.net/manual/en/language.errors.php7.php
quelle
Fatal error: Trait 'FailedTrait' not found in
bei der Verwendung abzufangenReflectionClass
?include "filename.php"
stattdessen in dentry
Block zu packen , dannThrowable
funktioniert catch-Block zumindest fürParseError
.Ich habe eine Möglichkeit entwickelt, alle Fehlertypen in PHP (fast alle) zu erfassen! Ich bin mir nicht sicher über E_CORE_ERROR (ich denke, es wird nicht nur für diesen Fehler funktionieren)! Bei anderen schwerwiegenden Fehlern (E_ERROR, E_PARSE, E_COMPILE ...) funktioniert dies jedoch mit nur einer Fehlerbehandlungsfunktion! Da geht meine Lösung:
Fügen Sie den folgenden Code in Ihre Hauptdatei (index.php) ein:
quelle
Sie können schwerwiegende Fehler nicht abfangen / behandeln, aber Sie können sie protokollieren / melden. Zum schnellen Debuggen habe ich eine Antwort auf diesen einfachen Code geändert
quelle
Sie können innerhalb einer registrierten Abschaltfunktion wie folgt keine Ausnahme auslösen:
Sie können Anforderungen jedoch erfassen und auf eine andere Seite umleiten.
quelle
Wenn Sie PHP> = 5.1.0 verwenden, machen Sie einfach so etwas mit der ErrorException-Klasse:
quelle
Gute Lösung in Zend Framework 2:
Mit dieser Klasse können Sie die spezifische
ErrorHandler
manchmal starten, wenn Sie es brauchen. Und dann können Sie auch den Handler stoppen.Verwenden Sie diese Klasse zB wie folgt:
Link zum vollständigen Klassencode:
https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/ErrorHandler.php
Eine vielleicht bessere Lösung ist die von Monolog :
Link zum vollständigen Klassencode:https://github.com/Seldaek/monolog/blob/master/src/Monolog/ErrorHandler.php
Es kann auch FATAL_ERRORS mit der
register_shutdown_function
Funktion verarbeiten. Gemäß dieser Klasse ist ein FATAL_ERROR eine der folgendenarray(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)
.quelle
Ich muss schwerwiegende Fehler für die Produktion behandeln, um stattdessen eine statisch gestaltete 503 Service Unavailable HTML-Ausgabe anzuzeigen . Dies ist sicherlich ein vernünftiger Ansatz, um "schwerwiegende Fehler zu erkennen". Folgendes habe ich getan:
Ich habe eine benutzerdefinierte Fehlerbehandlungsfunktion "error_handler", die meine HTML-Seite "503 service notavailable" auf jedem E_ERROR, E_USER_ERROR usw. anzeigt. Diese wird jetzt in der Shutdown-Funktion aufgerufen und fängt meinen schwerwiegenden Fehler ab.
Wenn der Fehler in meiner benutzerdefinierten error_handler-Funktion E_ERROR, E_USER_ERROR usw. ist, rufe ich ebenfalls auf
@ob_end_clean();
um den Puffer zu leeren und so die PHP-Meldung "Schwerwiegender Fehler" zu entfernen.Beachten Sie die strengen isset () - Prüfungen und
@
Stummschalten da unsere error_handler-Skripte keine Fehler generieren sollen.Wenn Sie Keparo weiterhin zustimmen, wird das Abfangen schwerwiegender Fehler den Zweck des "FATAL-Fehlers" zunichte machen, sodass Sie nicht wirklich für die weitere Verarbeitung vorgesehen sind. Führen Sie bei diesem Herunterfahren keine mail () -Funktionen aus, da Sie mit Sicherheit den Mailserver oder Ihren Posteingang sichern werden. Protokollieren Sie diese Vorkommen lieber in einer Datei und planen Sie einen Cron- Job, um diese error.log- Dateien zu finden und an Administratoren zu senden .
quelle
PHP hat schwerwiegende Fehler. Sie sind als E_RECOVERABLE_ERROR definiert. Das PHP-Handbuch beschreibt einen E_RECOVERABLE_ERROR als:
Sie können diese "schwerwiegenden" Fehler "abfangen", indem Sie set_error_handler () verwenden und nach E_RECOVERABLE_ERROR suchen. Ich finde es nützlich, eine Ausnahme auszulösen, wenn dieser Fehler abgefangen wird. Dann können Sie try / catch verwenden.
Diese Frage und Antwort bietet ein nützliches Beispiel: Wie kann ich einen "abfangbaren schwerwiegenden Fehler" bei Hinweisen auf PHP-Typen abfangen?
E_ERROR-Fehler können jedoch behandelt, aber nicht behoben werden, da sich die Engine in einem instabilen Zustand befindet.
quelle
Hier ist nur ein netter Trick, um die aktuelle error_handler-Methode zu erhalten =)
Auch das möchte ich beachten, wenn Sie anrufen
PHP zeigt den Fehler nicht mehr an. Andernfalls wird der Fehlertext vor Ihrem Fehlerbehandler an den Client gesendet.
quelle
Da die meisten Antworten hier unnötig ausführlich sind, ist hier meine nicht hässliche Version der am besten bewerteten Antwort:
quelle
Nicht wirklich. Schwerwiegende Fehler werden so genannt, weil sie schwerwiegend sind. Sie können sich nicht von ihnen erholen.
quelle
Ich habe diese Funktion entwickelt, um Code zu "sandboxen", der einen schwerwiegenden Fehler verursachen kann. Da Ausnahmen, die vom Abschluss ausgelöst werden
register_shutdown_function
, nicht vom vor schwerwiegenden Fehleraufrufstapel ausgegeben werden, muss ich diese Funktion beenden, um eine einheitliche Verwendung zu ermöglichen.quelle
Es gibt bestimmte Umstände, unter denen sogar schwerwiegende Fehler auftreten sollten (möglicherweise müssen Sie vor dem ordnungsgemäßen Beenden einige Aufräumarbeiten durchführen und sterben nicht einfach.).
Ich habe einen pre_system-Hook in meinem CodeIgniter implementiert Anwendungen damit ich meine schwerwiegenden Fehler per E- kann. Dies hat mir geholfen, Fehler zu finden, die nicht gemeldet wurden (oder gemeldet wurden, nachdem sie behoben wurden, da ich bereits davon wusste :)).
Sendemail prüft, ob der Fehler bereits gemeldet wurde, damit Sie nicht mehrmals mit bekannten Fehlern als Spam versendet werden.
quelle