Na pytanie SO, które tu zadałem , na temat jakiegoś kodu, którego nie byłem pewien, ktoś odpowiedział: „BTW, okropny kod: często używa symbolu tłumiącego błędy (@)”.
Czy istnieje powód, dla którego jest to zła praktyka? Z takimi rzeczami jak:
$db=@new mysqli($db_info) or die('Database error');
, pozwala mi wyświetlić tylko niestandardowy komunikat o błędzie. Bez tłumienia błędów nadal wyświetlałby typowy komunikat PHP:
Ostrzeżenie : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo nie powiodło się: Żaden taki host nie jest znany. w ścieżce \ file \ w wierszu 6
a także „Błąd bazy danych”.
Czy eliminowanie błędów jest zawsze złe, a jeśli tak, to co konkretnie w powyższym jest złe?
Aktualizacja: faktyczny kod, którego używam to:
or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b><br />Error occurred on line <b>' . __LINE__ . '</b> of <b>' . __FILE__ . '</b>' : ''))
który usuwa wszystkie poprzednie dane wyjściowe i wyświetla komunikat o błędzie. Zatem fakt, że komunikat o błędzie nie zawiera szczegółowych informacji o tym, co się konkretnie wydarzyło (co ludzie sugerują jako przyczynę złego tłumienia błędów) jest nieistotny.
źródło
or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))
Odpowiedzi:
Myślę, że postępujesz właściwie, tłumiąc błąd, ponieważ wdrażasz własną obsługę błędów.
Łatwiej byłoby rozważyć odpowiednik np. W Javie. Pomijanie błędu przy użyciu
@
jest analogiczne do połykania wyjątku. Poniższy kod, podobny do twojego, jest rozsądny:(Cóż, w Javie nie chciałbyś, aby silnik serwletu zginął, ale masz pomysł.)
Nie jest to jednak dopuszczalne:
Większość eliminacji błędów PHP odbywa się niedbale, analogicznie do drugiego przykładu, stąd reakcja kolana na twój kod.
źródło
Eliminowanie błędów jest złe, ponieważ nie tylko ukrywa informacje, które już znasz ( coś poszło nie tak). Może także ukrywać informacje niezbędne do debugowania, których nie jesteś świadomy ( co , gdzie i dlaczego ).
W tym konkretnym przykładzie „ Błąd bazy danych ” nie jest bardzo dobrym komunikatem o błędzie. Coś poszło nie tak z DB. Niezbyt pouczające. „ Ostrzeżenie: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo nie powiodło się: Żaden taki host nie jest znany. w jakimś \ pliku \ ścieżce w linii 6 ”jest w rzeczywistości lepszy komunikat o błędzie. Podaje lokalizację i przyczynę problemu. Możesz od razu wskoczyć i rozpocząć debugowanie, ponieważ błąd został już zlokalizowany.
Oczywiście, projektanci bibliotek czasami mają tendencję do przywoływania wielu nieistotnych ostrzeżeń. Nie znam PHP wystarczająco dobrze, aby wiedzieć, czy ma sposób na odfiltrowanie ostrzeżeń, które Cię nie interesują. Wiem, że czytanie przez setkę linii stacktrace nie jest zbyt pouczające. Ale prawidłowa odpowiedź na zbyt wiele informacji nie polega na zmniejszeniu ilości informacji do zera , ale na pewnym etapie odfiltrowaniu nieistotnych części.
@
Operator nie ma tego ziarnistość (to motto to wszystko albo nic ), a zatem nie jest odpowiednim narzędziem do efektywnego zarządzania błędu.Istnieją przypadki, gdy wiesz, że pewien błąd będzie podkręcić, a ustalenia rzeczywistego problemu jest droższe niż wyciszanie komunikat (i cierpienie potencjalnego fallout od tego). Może tak być w przypadku jednorazowego skryptu, ale wbicie palców w uszy i „ la la la ” nie jest profesjonalną reakcją na (potencjalne) błędy.
źródło
die
nie jest odpowiednia dla żadnego z nich. A szczegółowe informacje powinny przejść do dziennika, niezależnie od tego, co wyświetlasz użytkownikowi .display_errors
wyłącz, włączlog_errors
i jesteś całkiem dobry, zrób to, co chcesz, po wykryciu błędu, ale nie wyrzucaj go.Eliminowanie błędów jest złe, ponieważ ukrywa problem, o którym niejednokrotnie nawet nie jesteśmy świadomi, i może powodować nieoczekiwane zachowanie, które może okazać się bardzo kosztowne w niektórych krytycznych aplikacjach, np. W aplikacjach używanych w domenach finansowych, zdrowotnych i obronnych.
Nie jest również dobrym pomysłem, aby nieobsługiwane wyjątki w kodzie i wyświetlać użytkownikowi rzeczywiste komunikaty o błędach, ponieważ może to powodować problemy z bezpieczeństwem, ponieważ komunikaty o błędach zwykle ujawniają wiele informacji o kodzie, co może pomóc złośliwym użytkownikom i hakerom w manipulowaniu system.
Tak więc dobrą praktyką jest radzenie sobie z błędami na różnych poziomach, np. Na najwyższym poziomie możesz poradzić sobie z błędem, po prostu logując się do rzeczywistego błędu i pokazując użytkownikowi prosty i przyjazny komunikat.
źródło
Tak, operator eliminujący błędy jest ogólnie złym pomysłem.
Powinieneś zarządzać raportowaniem błędów w konfiguracji (
php.ini
). Możesz więc wybrać inne ustawienie dla każdego środowiska (np. Pozostaw ostrzeżenia w fazie rozwoju i ukryj je w środowisku produkcyjnym).Jedyną sytuacją, w której użycie
@
może mieć sens, jest tworzenie biblioteki dla innych programistów. Jeśli zdecydujesz się zrobić coś, co spowoduje wyświetlenie ostrzeżenia i nie chcesz drażnić użytkowników swojej biblioteki ostrzeżeniem, które nie zależy od nich,@
może to być rozwiązanie.Nie mogę wymyślić żadnego innego zastosowania.
źródło