billrichards
billrichards

Reputation: 2060

PHP - is it possible to use custom exception handler (set_exception_handler) inside a __destruct() method?

Is there way to use a custom exception handler, instead of the default exception handler, inside a class's __destruct method?

For example:

function myExceptionHandler($e)
{
    echo "custom exception handler";
    if(is_object($e) && method_exists($e,'getMessage'))
        echo $e->getMessage();
}
set_exception_handler('myExceptionHandler');
class MyClass {
    public function __construct()
    {
        // myExceptionHandler handles this exception
        //throw new Exception("Exception from " . __METHOD__);
    }

    public function doStuff()
    {
        // myExceptionHandler handles this exception
        //throw new Exception("Exception from " . __METHOD__);
    }

    public function __destruct()
    {
        // default exception handler 
        throw new Exception("Exception from " . __METHOD__);
    }

}

$myclass = new MyClass();
$myclass->doStuff();

Even if set_exception_handler is called within the __destruct method, the default handler is still used:

    public function __destruct()
    {
        $callable = function($e)
        {
            echo "custom exception handler".PHP_EOL;
            if(is_object($e) && method_exists($e,'getMessage'))
                echo $e->getMessage();
        };
        set_exception_handler($callable);
        throw new Exception("Exception from " . __METHOD__); // default exception handler
    }

Upvotes: 0

Views: 105

Answers (2)

Nigel Ren
Nigel Ren

Reputation: 57121

From the manual page

Note:

Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.

So using exceptions in a destructor is probably a bad idea in the first place. There may not be any of your code around when the script has finished to process the exception that is thrown.

Perhaps this code would be better placed in a close() method of the class instead.

Upvotes: 1

Millard
Millard

Reputation: 1157

Maybe something like this?

<?php

class MyException extends Exception {
    public function __construct() {
        parent::__construct('my exception');
    }
}

class MyClass {
    public function __construct()
    {
        // myExceptionHandler handles this exception
        //throw new Exception("Exception from " . __METHOD__);
    }

    public function doStuff()
    {
        // myExceptionHandler handles this exception
        //throw new Exception("Exception from " . __METHOD__);
    }

    public function __destruct()
    {
        // default exception handler 
        throw new MyException();
    }

}

$myclass = new MyClass();
$myclass->doStuff();

Upvotes: 1

Related Questions