restore_exception_handler()
Learn how PHP's restore_exception_handler() pops the current global exception handler off the stack and reactivates the previous one, with runnable examples.
Introduction
PHP lets you install a global exception handler with set_exception_handler() — a callback that runs whenever an exception bubbles all the way up uncaught. restore_exception_handler() is the counterpart: it removes the handler currently on top of the stack and reactivates the one that was active before it. This page covers what the function does, its exact return value, and when reaching for it is the right move.
How the exception handler stack works
Each call to set_exception_handler() pushes a handler onto an internal stack. Only the top of the stack is active at any moment. restore_exception_handler() pops the top entry, so the previously installed handler (or PHP's built-in default, if the stack becomes empty) takes over again.
This push/pop model is what makes the function useful: a library or a block of code can temporarily install its own handler, then restore the caller's handler when it is done — without needing to know what that handler was.
If you are new to exceptions, start with PHP Exceptions and the try/catch chapter; restore_exception_handler() only deals with the global uncaught-exception handler, not the catch blocks you write inline.
Syntax
restore_exception_handler(): trueThe function takes no parameters and always returns true. It does not return the handler it removed — to read the previous handler, capture the value returned by set_exception_handler() (which gives you the handler that was active before it was set).
Example: temporarily overriding the handler
The snippet below installs a base handler, then temporarily overrides it for one section of code and restores the base handler afterward:
<?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");Output:
Base: something failedThe temp_handler was popped by restore_exception_handler(), so when the uncaught exception reaches the top of the script, base_handler runs instead. Note that the global handler only fires for uncaught exceptions — anything wrapped in a matching try/catch never reaches it.
Reading the previous handler
restore_exception_handler() itself does not hand back the removed handler. If you need to know which callable was active before you overrode it, save the return value of 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_handlerWhen to use it
- Scoped overrides. A routine installs its own handler for the duration of a task, then calls
restore_exception_handler()so the rest of the program keeps the original behavior. - Libraries. Code that does not own the global handler can borrow it temporarily and politely give it back.
- Cleanup and shutdown logic. Undo a temporary handler before the script exits so it does not leak into later code.
It affects exception handlers only — to restore a standard error handler set with set_error_handler(), use restore_error_handler() instead.
Diagram
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]