Обработка ошибок PHP: die () против trigger_error () против исключения throw

119

Что касается обработки ошибок в PHP - насколько я знаю, есть 3 стиля:

  1. die()или exit()стиль:

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

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

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

Теперь в руководстве по PHP используются все три метода.

  • Я хочу знать, какой стиль мне лучше выбрать и почему?

  • Являются ли эти 3 капли заменой друг друга и, следовательно, могут ли они использоваться взаимозаменяемо?

Немного ОТ: Это только мне кажется, или все думают, что вариантов обработки ошибок PHP слишком много и это сбивает с толку разработчиков php?

CuriousMind
источник
4
Это не «стили». Это разные языковые особенности. Для разных целей.
Марио
11
@mario: чем отличаются отступы от цели ? Пожалуйста, просветите меня :)
CuriousMind
Вы правильно задали вопрос. Спасибо за вопрос
Бухгалтер م

Ответы:

86

Первый никогда не следует использовать в производственном коде, поскольку он передает информацию, не имеющую отношения к конечным пользователям (пользователь не может ничего сделать с «Невозможно подключиться к базе данных» ).

Вы выбрасываете исключения, если знаете, что в определенной критической точке кода ваше приложение может выйти из строя, и вы хотите, чтобы ваш код восстанавливался на нескольких уровнях вызовов.

trigger_error()позволяет вам создавать подробные отчеты об ошибках (используя разные уровни сообщений об ошибках), и вы можете скрыть эти ошибки от конечных пользователей (используя set_error_handler()), но при этом они будут отображаться вам во время тестирования.

Также trigger_error() может генерировать нефатальные сообщения, важные во время разработки, которые могут быть подавлены в производственном коде с помощью специального обработчика ошибок. Вы также можете создавать фатальные ошибки ( E_USER_ERROR), но их невозможно исправить. Если вы запускаете один из них, выполнение программы останавливается на этом этапе. Вот почему для фатальных ошибок следует использовать исключения. Таким образом, у вас будет больше контроля над потоком вашей программы:

// 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');
}

Здесь, если gather_data()просто каркнул (используя E_USER_ERRORили die()), есть шанс, предыдущийINSERT операторы попали бы в вашу базу данных, даже если бы они не были желательны, и вы не могли бы контролировать, что произойдет дальше.

Линус Клин
источник
2
Итак, из trigger_error()& исключения исключений: какой из них я должен использовать и когда?
CuriousMind
@Gaurish См. Добавленный пример по этому поводу.
Линус Клин
2
Прочитав ваш пример, я думаю, что теперь я лучше понимаю цель исключения исключения. Спасибо :)
CuriousMind
1
@Pacerier Это действительно зависит от конфигурации сервера. Система может быть настроена на автоматическую фиксацию по умолчанию, следовательно, явное ROLLBACK. Этот пример псевдокода охватывает оба случая: серверы, которые не настроены на автоматическую фиксацию ( COMMITтребуется оператор), и те, которые это делают.
Linus Kleen
1
@LinusKleen, разве автоматическая фиксация не отключается, когда мы запускаем линию query('START TRANSACTION');?
Pacerier
10

Обычно я использую первый способ для простой отладки кода разработки. Не рекомендуется к производству. Лучший способ - создать исключение, которое вы можете перехватить в других частях программы и выполнить некоторую обработку ошибок.

Эти три стиля не заменяют друг друга. Первый - это вовсе не ошибка, а просто способ остановить скрипт и вывести некоторую отладочную информацию для ручного анализа. Второй не является ошибкой как таковой, но будет преобразован в ошибку, если вы ее не поймаете. Последний запускает реальную ошибку в движке PHP, которая будет обрабатываться в соответствии с конфигурацией вашей среды PHP (в некоторых случаях отображается пользователю, в других случаях просто регистрируется в файле или не сохраняется вообще).

Эмиль Викстрём
источник
1
Что происходит, когда исключение генерируется, но не обнаруживается? я думаю, это вызовет фатальную ошибку. И с trigger_error()этим происходит то же самое. так какая разница?
CuriousMind
4
Разница в том, что вы можете перехватить исключение и обработать его любым удобным для вас способом.
Эмиль Викстрём