Muszę złapać ostrzeżenia wyrzucane z niektórych rodzimych funkcji php, a następnie je obsłużyć.
Konkretnie:
array dns_get_record ( string $hostname [, int $type= DNS_ANY [, array &$authns [, array &$addtl ]]] )
Wyświetla ostrzeżenie, gdy zapytanie DNS nie powiedzie się.
try
/ catch
nie działa, ponieważ ostrzeżenie nie jest wyjątkiem.
Mam teraz 2 opcje:
set_error_handler
wygląda na przesadę, ponieważ muszę go używać do filtrowania każdego ostrzeżenia na stronie (czy to prawda?);Dostosuj raportowanie / wyświetlanie błędów, aby ostrzeżenia te nie były wyświetlane na ekranie, a następnie sprawdź wartość zwracaną; jeśli tak
false
, nie znaleziono rekordów dla nazwy hosta.
Jaka jest tutaj najlepsza praktyka?
php
error-handling
try-catch
użytkownik121196
źródło
źródło
Odpowiedzi:
Ustaw i przywróć moduł obsługi błędów
Jedną z możliwości jest ustawienie własnego modułu obsługi błędów przed wywołaniem i przywrócenie poprzedniego modułu obsługi błędów za pomocą
restore_error_handler()
.Możesz skorzystać z tego pomysłu i napisać program obsługi błędów wielokrotnego użytku, który rejestruje błędy.
Przekształcanie błędów w wyjątki
Możesz użyć
set_error_handler()
iErrorException
klasy, aby zamienić wszystkie błędy php w wyjątki.Ważną rzeczą, na którą należy zwrócić uwagę podczas korzystania z własnego modułu obsługi błędów, jest to, że pominie ono
error_reporting
ustawienie i przekaże wszystkie błędy (powiadomienia, ostrzeżenia itp.) Do modułu obsługi błędów. Możesz ustawić drugi argument,set_error_handler()
aby zdefiniować typy błędów, które chcesz otrzymać, lub uzyskać dostęp do bieżącego ustawienia za pomocą... = error_reporting()
procedury obsługi błędów.Tłumienie ostrzeżenia
Inną możliwością jest pomijanie połączenia z operatorem @ i sprawdzanie
dns_get_record()
późniejszej wartości zwrotu . Ale odradzałbym to, ponieważ błędy / ostrzeżenia są wywoływane w celu obsługi, a nie tłumienia.źródło
Rozwiązaniem, które naprawdę działa, było ustawienie prostej procedury obsługi błędów za pomocą
E_WARNING
parametru, na przykład:źródło
callable
można tu również użyć anonimowego zamiast ciągu znaków z deklaracją funkcjitrow new \Exception($errstr, $errno);
środkuwarning_handler
. Dzięki.Bądź ostrożny z
@
operatorem - eliminując ostrzeżenia, eliminuje również błędy krytyczne. Spędziłem dużo czasu debugując problem w systemie, w którym ktoś napisał@mysql_query( '...' )
. Problem polegał na tym, że obsługa mysql nie została załadowana do PHP i spowodowało to cichy błąd krytyczny. To będzie bezpieczne dla tych rzeczy, które są częścią jądra PHP, ale proszę go używać z rozwagą.Brak dalszych wyników - powodzenia przy debugowaniu tego!
Tym razem możemy zobaczyć, dlaczego się nie udało.
źródło
Chciałem spróbować / złapać ostrzeżenie, ale jednocześnie zachować rejestrowanie zwykle ostrzeżenie / błąd (np
/var/log/apache2/error.log
); do którego przewodnik musi zwrócićfalse
. Ponieważ jednak instrukcja „rzucaj nowe ...” zasadniczo przerywa wykonanie, należy wykonać sztuczkę „zawinąć w funkcję”, omówioną również w:Czy istnieje statyczny sposób na zgłoszenie wyjątku w php
Lub w skrócie:
EDYCJA: po dokładniejszym sprawdzeniu okazuje się, że to nie działa: „
return false && throwErrorException ...
” w zasadzie nie wyrzuci wyjątku i po prostu zaloguje się do dziennika błędów; usunięcie części „false &&
”, jak w „return throwErrorException ...
”, spowoduje, że zgłoszenie wyjątku zadziała, ale nie zaloguje się do dziennika error_log ... Nadal będę to publikował, ponieważ nie widziałem tego zachowania w innym miejscu.źródło
Prawdopodobnie powinieneś spróbować całkowicie pozbyć się ostrzeżenia, ale jeśli nie jest to możliwe, możesz poprzedzić wywołanie za pomocą @ (tj. @Dns_get_record (...)), a następnie użyć wszelkich informacji, które możesz dowiedzieć się, czy ostrzeżenie się wydarzyło albo nie.
źródło
Normalnie nigdy nie powinieneś używać @, chyba że jest to jedyne rozwiązanie. W tym konkretnym przypadku należy najpierw użyć funkcji dns_check_record, aby dowiedzieć się, czy rekord istnieje.
źródło
Połączenie tych wierszy kodu wokół
file_get_contents()
wywołania zewnętrznego adresu URL pomogło mi obsługiwać ostrzeżenia takie jak „ nie udało się otworzyć strumienia: Przekroczono limit czasu połączenia ” znacznie lepiej:To rozwiązanie działa również w kontekście obiektowym. Możesz użyć go w funkcji:
źródło
Jeśli się
dns_get_record()
nie powiedzie, powinien powrócićFALSE
, aby można było wyłączyć ostrzeżenie za pomocą,@
a następnie sprawdzić wartość zwracaną.źródło
spróbuj sprawdzić, czy zwraca wartość logiczną, a następnie możesz po prostu ustawić ją jako warunek. Zetknąłem się z tym z oci_execute (...), który zwracał pewne naruszenia za pomocą moich unikalnych kluczy.
źródło
FolderStructure
CustomException.php
wystarczy dołączyć powyższy plik do pliku skryptu w ten sposób
index.php
źródło
Zalecałbym używanie @ do tłumienia ostrzeżeń tylko wtedy, gdy jest to prosta operacja (np. $ Prop = @ ($ high / ($ width - $ depth)); aby pominąć podział przez zero ostrzeżeń). Jednak w większości przypadków lepiej sobie z tym poradzić.
źródło