PHP Помилка оброблення: die () Vs_pro_error () Vs кидок Виняток


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 краплі заміни один одного і тому можуть бути взаємозамінні?

Трохи OT: Це лише я або всі вважають, що варіантів обробки помилок PHP занадто багато, наскільки це бентежить розробників PHP?


4
Це не "стилі". Вони різні мовні особливості. Для різних цілей.
mario

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даних (потрібна операція), і ті, що роблять.
Лінус Клін

1
@LinusKleen, чи не вимкнено автокомісію після запуску лінії query('START TRANSACTION');?
Pacerier

10

Зазвичай я використовую перший спосіб для простої налагодження в коді розробки. Не рекомендується для виробництва. Найкращий спосіб - викинути виняток, який ви можете впізнати в інших частинах програми та зробити деякі помилки.

Три стилі - це не замінювальні елементи, що замінюються. Перший - це зовсім не помилка, а просто спосіб зупинити скрипт і вивести інформацію про налагодження, щоб ви вручну розбирали. Друга сама по собі не є помилкою, але вона буде перетворена на помилку, якщо ви її не знайдете. Останній викликає справжню помилку в двигуні PHP, яка буде оброблятися відповідно до конфігурації вашого середовища PHP (в деяких випадках, показаних користувачеві, в інших випадках просто увійшли до файлу або зовсім не збереглися).


1
Що відбувається, коли виняток кидається, але не потрапляє? це, мабуть, призведе до фатальної помилки. І з trigger_error()тим же відбувається. так яка різниця?
CuriousMind

4
Різниця полягає в тому, що ви можете зловити виняток і обробити його будь-яким способом.
Еміль Вікстрьом
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.