Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як перетворити попередження PHP на винятки?

У PHP є дві системи повідомлень про проблеми: винятки (throw) і помилки рушія - E_WARNING, E_NOTICE, E_DEPRECATED. Попередження за замовчуванням лише пишеться в лог, а виконання продовжується - часто з неправильними даними:

$content = file_get_contents('/missing.txt');   // Warning, $content === false
$data = json_decode($content);                  // працюємо далі з false

set_error_handler перехоплює такі помилки. Найпоширеніший прийом - перетворити їх на ErrorException:

set_error_handler(function (int $severity, string $message, string $file, int $line): bool {
    if (! (error_reporting() & $severity)) {
        return false;   // помилку придушено через @ чи налаштування
    }

    throw new ErrorException($message, 0, $severity, $file, $line);
});

Тепер file_get_contents для неіснуючого файлу кидає виняток, і код не піде далі з false.

Laravel робить це за вас: обробник помилок фреймворку (HandleExceptions) перетворює попередження й notice на ErrorException. Тому в Laravel-застосунку «Undefined array key» - це виняток зі стек-трейсом, а не рядок у лозі. Застарілі (E_DEPRECATED) Laravel на винятки не перетворює, а пише в окремий канал логів, якщо його налаштовано (LOG_DEPRECATIONS_CHANNEL).

Що варто знати:

  • Фатальні помилки (E_ERROR, вичерпання пам'яті) set_error_handler не перехоплює. Для них - register_shutdown_function() з error_get_last().
  • Оператор @ придушує попередження, але приховує й справжні проблеми. Краще перевіряти результат функції явно.
  • Сучасні функції часто вже кидають винятки: json_decode(..., flags: JSON_THROW_ON_ERROR), random_int(), більшість методів класів SPL і intl.

Докладніше в документації: set_error_handler

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання