Obsługa błędów PHP: die () kontra trigger_error () kontra wyjątek

119

Odnośnie obsługi błędów w PHP - z tego co wiem, istnieją 3 style:

  1. die()lub exit()styl:

    $con = mysql_connect("localhost","root","password");
    
    if (!$con) {
     die('Could not connect: ' . mysql_error());
    }
  2. throw Exception styl:

     if (!function_exists('curl_init')) {
    
          throw new Exception('need the CURL PHP extension. 
                               Recomplie PHP with curl');
        }
  3. trigger_error() styl:

    if(!is_array($config) && isset($config)) {
            trigger_error('Error: config is not an array or is not set', E_USER_ERROR);
        }

Teraz w podręczniku PHP są używane wszystkie trzy metody.

  • Chcę wiedzieć, który styl powinienem preferować i dlaczego?

  • Czy te 3 spadają zamienniki siebie nawzajem i dlatego mogą być używane zamiennie?

Trochę OT: Czy to tylko ja, czy wszyscy uważają, że opcji obsługi błędów PHP jest po prostu zbyt wiele do tego stopnia, że ​​dezorientują programistów php?

CuriousMind
źródło
4
To nie są „style”. Są to różne funkcje językowe. Do różnych celów.
mario
11
@mario: jakie są różne cele z wcięciem ? Proszę mnie oświecić :)
CuriousMind
Świetnie zadałeś pytanie. dzięki za pytanie
Księgowy م

Odpowiedzi:

86

Pierwszego z nich nie należy nigdy używać w kodzie produkcyjnym, ponieważ przenosi informacje nieistotne dla użytkowników końcowych (użytkownik nie może nic zrobić z „Nie można połączyć się z bazą danych” ).

Zgłaszasz wyjątki, jeśli wiesz, że w pewnym krytycznym punkcie kodu aplikacja może się nie powieść i chcesz, aby kod został odzyskany na wielu poziomach wywołań.

trigger_error() pozwala na szczegółowe raportowanie błędów (używając różnych poziomów komunikatów o błędach) i możesz ukryć te błędy przed użytkownikami końcowymi (używając set_error_handler() ), ale nadal wyświetlać je podczas testowania.

trigger_error()Może również generować niekrytyczne komunikaty ważne podczas programowania, które można pominąć w kodzie produkcyjnym za pomocą niestandardowej procedury obsługi błędów. Możesz także generować błędy krytyczne ( E_USER_ERROR), ale nie można ich naprawić. Jeśli wyzwolisz jedną z nich, wykonywanie programu zatrzyma się w tym momencie. Dlatego w przypadku błędów krytycznych należy stosować wyjątki. W ten sposób będziesz mieć większą kontrolę nad przepływem programu:

// Example (pseudo-code for db queries):

$db->query('START TRANSACTION');

try {
    while ($row = gather_data()) {
       $db->query('INSERT INTO `table` (`foo`,`bar`) VALUES(?,?)', ...);
    }
    $db->query('COMMIT');
} catch(Exception $e) {
    $db->query('ROLLBACK');
}

Tutaj, jeśli gather_data()po prostu rechotał (używając E_USER_ERRORlub die()), jest szansa, poprzednie INSERTstwierdzenia trafiłyby do twojej bazy danych, nawet jeśli nie byłyby pożądane i nie miałbyś kontroli nad tym, co będzie dalej.

Linus Kleen
źródło
2
więc z trigger_error()& rzucania wyjątków: który z nich powinienem używać i kiedy?
CuriousMind
@Gaurish Zobacz dodany przykład.
Linus Kleen
2
Po przeczytaniu twojego przykładu myślę, że teraz lepiej rozumiem cel rzucania wyjątków. Dzięki :)
CuriousMind
1
@Pacerier W rzeczywistości zależy to od konfiguracji serwera. System może być domyślnie skonfigurowany do automatycznego zatwierdzania , stąd jawne ROLLBACK. Ten przykład pseudokodu obejmuje oba przypadki: serwery, które nie są skonfigurowane do automatycznego zatwierdzania ( COMMITinstrukcja jest wymagana) i te, które to robią.
Linus Kleen,
1
@LinusKleen, czy automatyczne zatwierdzanie nie jest wyłączone po uruchomieniu linii query('START TRANSACTION');?
Pacerier,
10

Zwykle używam pierwszego sposobu prostego debugowania w kodzie programistycznym. Nie jest zalecany do produkcji. Najlepszym sposobem jest zgłoszenie wyjątku, który można przechwycić w innych częściach programu i zająć się obsługą błędów.

Te trzy style nie są zamiennikami typu drop-in. Pierwsza z nich wcale nie jest błędem, a jedynie sposobem na zatrzymanie skryptu i wyświetlenie informacji o debugowaniu, które można ręcznie przeanalizować. Drugi nie jest błędem per se, ale zostanie przekształcony w błąd, jeśli go nie złapiesz. Ten ostatni wywołuje prawdziwy błąd w silniku PHP, który będzie obsługiwany zgodnie z konfiguracją twojego środowiska PHP (w niektórych przypadkach pokazywany użytkownikowi, w innych po prostu zalogowany do pliku lub w ogóle nie zapisany).

Emil Vikström
źródło
1
Co się dzieje, gdy wyjątek zostanie zgłoszony, ale nie zostanie przechwycony? przypuszczam, że spowoduje to fatalny błąd. I trigger_error()dzieje się to samo. więc jaka jest różnica?
CuriousMind
4
Różnica polega na tym, że możesz złapać wyjątek i obsłużyć go w dowolny sposób.
Emil Vikström