restore_exception_handler()
Узнайте, как PHP-функция restore_exception_handler() восстанавливает предыдущий глобальный обработчик исключений, с примерами кода.
Введение
PHP позволяет устанавливать глобальный обработчик исключений с помощью set_exception_handler() — функции обратного вызова, которая срабатывает всякий раз, когда исключение поднимается до самого верха необработанным. restore_exception_handler() — это её аналог: она удаляет обработчик, находящийся на вершине стека, и реактивирует тот, что был активен перед ним. На этой странице рассмотрено, что делает функция, её точное возвращаемое значение и когда её следует использовать.
Как работает стек обработчиков исключений
Каждый вызов set_exception_handler() помещает обработчик во внутренний стек. В любой момент активна только вершина стека. restore_exception_handler() извлекает верхний элемент, и управление переходит к ранее установленному обработчику (или к встроенному обработчику PHP по умолчанию, если стек опустеет).
Эта модель «добавления/извлечения» и делает функцию полезной: библиотека или блок кода могут временно установить собственный обработчик, а затем восстановить обработчик вызывающего кода по завершении работы — не зная, что это был за обработчик.
Если вы только знакомитесь с исключениями, начните с главы Исключения PHP и главы try/catch; restore_exception_handler() работает только с глобальным обработчиком необработанных исключений, а не с блоками catch, которые вы пишете встроенно.
Синтаксис
restore_exception_handler(): trueФункция не принимает никаких параметров и всегда возвращает true. Она не возвращает удалённый обработчик — чтобы получить предыдущий обработчик, сохраните значение, возвращённое set_exception_handler() (она возвращает обработчик, который был активен до её вызова).
Пример: временная замена обработчика
Фрагмент ниже устанавливает базовый обработчик, затем временно заменяет его для одного раздела кода и после этого восстанавливает базовый:
<?php
function base_handler($e) {
echo "Base: " . $e->getMessage() . "\n";
}
function temp_handler($e) {
echo "Temp: " . $e->getMessage() . "\n";
}
set_exception_handler('base_handler');
set_exception_handler('temp_handler'); // pushes temp on top
restore_exception_handler(); // pops temp, base is active again
// Because this exception is never caught, the active global handler runs:
throw new Exception("something failed");Вывод:
Base: something failedtemp_handler был извлечён из стека функцией restore_exception_handler(), поэтому когда необработанное исключение достигает верхнего уровня скрипта, вместо него запускается base_handler. Обратите внимание, что глобальный обработчик срабатывает только для необработанных исключений — всё, что перехватывается подходящим блоком try/catch, до него не доходит.
Получение предыдущего обработчика
restore_exception_handler() сама по себе не возвращает удалённый обработчик. Если вам нужно знать, какой callable был активен до того, как вы его переопределили, сохраните возвращаемое значение set_exception_handler():
<?php
set_exception_handler('base_handler');
// set_exception_handler() returns the handler it replaced:
$previous = set_exception_handler('temp_handler');
var_dump($previous); // string(12) "base_handler"
restore_exception_handler(); // back to base_handlerКогда использовать
- Локальные переопределения. Подпрограмма устанавливает собственный обработчик на время выполнения задачи, а затем вызывает
restore_exception_handler(), чтобы остальная часть программы сохранила исходное поведение. - Библиотеки. Код, не владеющий глобальным обработчиком, может временно его позаимствовать и корректно вернуть обратно.
- Логика очистки и завершения. Отмените временный обработчик перед завершением скрипта, чтобы он не затронул последующий код.
Функция влияет только на обработчики исключений — чтобы восстановить стандартный обработчик ошибок, установленный через set_error_handler(), используйте restore_error_handler().
Диаграмма
graph TD
A[set_exception_handler base] --> B[set_exception_handler temp pushes on top]
B --> C[restore_exception_handler pops temp]
C --> D[base handler active again]
D --> E[Uncaught exception runs base handler]