Mogę użyć, set_error_handler()
aby wyłapać większość błędów PHP, ale to nie działa na fatalne (E_ERROR
błędów ), takich jak wywołanie funkcji, która nie istnieje. Czy istnieje inny sposób na wyłapanie tych błędów?
Próbuję wywołać mail()
wszystkie błędy i korzystam z PHP 5.2.3.
php
fatal-error
za dużo php
źródło
źródło
Odpowiedzi:
Loguj krytyczne błędy używając
register_shutdown_function
, który wymaga PHP 5.2+:Będziesz musiał zdefiniować funkcje
error_mail
iformat_error
. Na przykład:Użyj Swift Mailer, aby napisać
error_mail
funkcję.Zobacz też:
źródło
mail("[email protected]", "My Site: FATAL ERROR", "Details: " . $errno . ' ' . $errstr . ' ' . $errfile . ' ' . $errline);
Właśnie wymyśliłem to rozwiązanie (PHP 5.2.0+):
Różne typy błędów są zdefiniowane w predefiniowanych stałych .
źródło
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()
musi być wcześniejsze niż jakikolwiek błąd krytyczny.use_1T_memory(); /* memory exhausted error here! */ register_shutdown_function('shutDownFunction');
nie będzie działać zgodnie z oczekiwaniami.PHP nie zapewnia konwencjonalnych sposobów wychwytywania i odzyskiwania po błędach krytycznych. Wynika to z faktu, że przetwarzanie zwykle nie powinno być odzyskiwane po wystąpieniu błędu krytycznego. Ciąg pasujący do bufora wyjściowego (jak sugeruje oryginalny post technika opisana na PHP.net) jest zdecydowanie odradzany. To po prostu niewiarygodne.
Problematyczne jest również wywoływanie funkcji mail () z poziomu metody obsługi błędów. Gdybyś miał dużo błędów, twój serwer pocztowy byłby załadowany pracą i mógłbyś znaleźć się z gnarly skrzynką odbiorczą. Aby tego uniknąć, możesz rozważyć uruchomienie crona, aby okresowo skanować dzienniki błędów i odpowiednio wysyłać powiadomienia. Możesz także zajrzeć do oprogramowania do monitorowania systemu, takiego jak Nagios .
Aby porozmawiać o rejestracji funkcji zamykania:
To prawda, że możesz zarejestrować funkcję zamykania, a to dobra odpowiedź.
Chodzi o to, że zazwyczaj nie powinniśmy próbować przywracać sprawności po błędach krytycznych, zwłaszcza nie używając wyrażenia regularnego w buforze wyjściowym. Odpowiedziałem na zaakceptowaną odpowiedź , która łączyła się z sugestią na php.net, która została zmieniona lub usunięta.
Ta sugestia polegała na zastosowaniu wyrażenia regularnego względem bufora wyjściowego podczas obsługi wyjątków, aw przypadku błędu krytycznego (wykrytego przez dopasowanie do dowolnego skonfigurowanego tekstu błędu, którego można się spodziewać), spróbuj wykonać pewnego rodzaju odzyskiwanie lub dalsze przetwarzanie. To nie byłaby zalecana praktyka (uważam, że dlatego też nie mogę znaleźć oryginalnej sugestii. Albo przeoczam ją, albo społeczność php zestrzeliła ją).
Warto zauważyć, że nowsze wersje PHP (około 5.1) wydają się wcześniej wywoływać funkcję zamykania, zanim zostanie wywołane wywołanie zwrotne buforowania wyjścia. W wersji 5 i wcześniejszych ta kolejność była odwrotna (po wywołaniu zwrotnym buforowania danych wyjściowych nastąpiła funkcja zamykania). Ponadto, ponieważ około 5.0.5 (czyli znacznie wcześniej niż wersja pytającego 5.2.3), obiekty są rozładowywane na długo przed wywołaniem zarejestrowanej funkcji zamykania, więc nie będzie można polegać na obiektach w pamięci dużo czegokolwiek.
Rejestracja funkcji zamykania jest więc w porządku, ale zadania, które powinna wykonać funkcja zamykania, prawdopodobnie ograniczają się do kilku delikatnych procedur zamykania.
Kluczową sprawą tutaj są tylko słowa mądrości dla każdego, kto natknie się na to pytanie i zapozna się z radą w pierwotnie przyjętej odpowiedzi. Nie regexuj bufora wyjściowego.
źródło
Wydaje się, że możliwe jest złapanie krytycznych błędów w inny sposób :)
źródło
Błędy krytyczne lub możliwe do odzyskania błędy krytyczne generują teraz instancje
Error
w PHP 7 lub wyższych wersjach . Jak wszystkie inne wyjątki,Error
obiekty można złapać za pomocątry/catch
bloku.Przykład:
https://3v4l.org/67vbk
Lub możesz użyć
Throwable
interfejsu, aby złapać wszystkie wyjątki.Przykład:
https://3v4l.org/Br0MG
Aby uzyskać więcej informacji: http://php.net/manual/en/language.errors.php7.php
źródło
Fatal error: Trait 'FailedTrait' not found in
podczas używaniaReflectionClass
?include "filename.php"
zamiast tego wtry
bloku, a następnieThrowable
przynajmniej złap blokParseError
.Opracowałem sposób na wyłapanie wszystkich typów błędów w PHP (prawie wszystkie)! Nie mam pewności co do E_CORE_ERROR (myślę, że nie będzie działać tylko w przypadku tego błędu)! Ale w przypadku innych błędów krytycznych (E_ERROR, E_PARSE, E_COMPILE ...) działa dobrze przy użyciu tylko jednej funkcji obsługi błędów! Oto moje rozwiązanie:
Umieść następujący kod w głównym pliku (index.php):
źródło
Nie możesz wychwycić / obsłużyć krytycznych błędów, ale możesz je zalogować / zgłosić. W celu szybkiego debugowania zmodyfikowałem jedną odpowiedź na ten prosty kod
źródło
Nie można wrzucić wyjątku do zarejestrowanej funkcji zamykania w następujący sposób:
Ale możesz przechwytywać i przekierowywać żądania na inną stronę.
źródło
Jeśli używasz PHP> = 5.1.0 Po prostu zrób coś takiego z klasą ErrorException:
źródło
Ładne rozwiązanie znalezione w Zend Framework 2:
Ta klasa pozwala
ErrorHandler
czasem rozpocząć konkretną, jeśli jest to potrzebne. Następnie możesz zatrzymać Handlera.Użyj tej klasy, np. W ten sposób:
Link do pełnego kodu klasy:
https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/ErrorHandler.php
Być może lepszym rozwiązaniem jest to od Monolog :
Link do pełnego kodu klasy:https://github.com/Seldaek/monolog/blob/master/src/Monolog/ErrorHandler.php
Może również obsługiwać FATAL_ERRORS za pomocą
register_shutdown_function
funkcji. Według tej klasy FATAL_ERROR jest jedną z poniższycharray(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)
.źródło
Muszę obsłużyć krytyczne błędy związane z produkcją, aby zamiast tego wyświetlić statyczny wynik HTML 503 Usługa niedostępna . Jest to z pewnością rozsądne podejście do „łapania błędów krytycznych”. Oto co zrobiłem:
Mam niestandardową funkcję obsługi błędów „moduł obsługi błędów”, która wyświetla moją stronę HTML „niedostępna usługa 503” na dowolnym elemencie E_ERROR, E_USER_ERROR itp. Zostanie ona teraz wywołana w funkcji zamykania, wychwytując mój błąd krytyczny,
w mojej niestandardowej funkcji modułu obsługi błędów, jeśli błąd to E_ERROR, E_USER_ERROR itp. Również wywołuję
@ob_end_clean();
aby opróżnić bufor, usuwając w ten sposób komunikat „fatal error” PHP.Zwróć uwagę na funkcje ścisłego sprawdzania i
@
wyciszania funkcji isset (), ponieważ nie chcemy, aby nasze skrypty obsługi błędów generowały błędy.Wciąż zgadzając się z Keparo, łapanie błędów krytycznych nie pozwala na osiągnięcie celu „FATAL error”, więc tak naprawdę nie jest przeznaczone do dalszego przetwarzania. Nie uruchamiaj żadnych funkcji mail () w tym procesie zamykania, ponieważ z pewnością utworzysz kopię zapasową serwera pocztowego lub skrzynki odbiorczej. Raczej zalogować tych zdarzeń do pliku i zaplanować cron zadanie, aby znaleźć tych error.log plików i wysłać je do administratorów.
źródło
PHP ma krytyczne błędy krytyczne. Są one zdefiniowane jako E_RECOVERABLE_ERROR. Podręcznik PHP opisuje E_RECOVERABLE_ERROR jako:
Możesz „złapać” te „krytyczne” błędy, używając set_error_handler () i sprawdzając E_RECOVERABLE_ERROR. Uważam, że przydatne jest zgłoszenie wyjątku, gdy ten błąd zostanie wykryty, wtedy możesz użyć try / catch.
To pytanie i odpowiedź stanowi przydatny przykład: Jak mogę złapać „krytyczny błąd krytyczny” na podpowiedzi typu PHP?
Błędy E_ERROR można jednak obsłużyć, ale nie można ich odzyskać, ponieważ silnik jest w niestabilnym stanie.
źródło
Oto po prostu fajna sztuczka, aby uzyskać bieżącą metodę modułu obsługi błędów =)
Również chcę zauważyć, że jeśli zadzwonisz
PHP przestaje wyświetlać błąd. W przeciwnym razie tekst błędu zostanie wysłany do klienta przed obsługą błędów.
źródło
Ponieważ większość odpowiedzi tutaj jest niepotrzebnie pełna, oto moja nieprzyzwoita wersja najlepiej głosowanej odpowiedzi:
źródło
Nie całkiem. Błędy krytyczne nazywane są tak, ponieważ są śmiertelne. Nie możesz się od nich odzyskać.
źródło
Opracowałem tę funkcję, aby umożliwić „piaskownicę” kodu, który może spowodować błąd krytyczny. Ponieważ wyjątki wyrzucone z zamknięcia
register_shutdown_function
nie są emitowane ze stosu wywołań błędów przed śmiercią, jestem zmuszony wyjść z tej funkcji, aby zapewnić jednolity sposób korzystania z niej.źródło
Są pewne okoliczności, w których należy wychwycić nawet fatalne błędy (być może trzeba będzie trochę posprzątać przed wyjściem z gracją i nie tylko umrzeć ...).
Zaimplementowałem hak pre_system w moim CodeIgniter aplikacjach , dzięki czemu mogę otrzymywać krytyczne błędy za pośrednictwem e-maili, a to pomogło mi znaleźć błędy, które nie zostały zgłoszone (lub zostały zgłoszone po ich naprawieniu, jak już o nich wiedziałem :)).
Sendemail sprawdza, czy błąd został już zgłoszony, aby nie wysyłać spamu znanymi błędami wiele razy.
źródło