处理异常并继续执行

时间:2012-03-05 21:51:38

标签: php exception-handling callback

[编辑 - 免责声明:这是一个非常糟糕的主意,请参阅实际解决方案的已接受答案。]

我使用set_exception_handler()函数定义自己的异常处理程序。处理程序执行后,我需要脚本继续。有没有办法做到这一点?

免责声明:我知道try-catch块,但我需要动态处理异常。每次调用Clazz :: foo()都会指定自己的异常,这些异常应由我的处理程序捕获。这就是我无法使用它的原因。

示例:

class Clazz {

    private static $exceptions;

    public static function foo(array $exceptions) {
        set_exception_handler(array(__CLASS__, "exception_handler"));
        self::$exceptions = $exceptions;
        throw new RandomException;
        echo "I need this to be printed!";
    }

    public static function exception_handler($exception) {
        // process the exception in my way...
        // if $exception in self::$exceptions than 1, else 2, fi
        restore_exception_handler();
        // continue in some way, like it has never happenned
    }

}

4 个答案:

答案 0 :(得分:4)

在启动文件中执行类似的操作

/**
 * Set the default exception handler.
 *
 * @param Exception $exception The exception to handle
 */
$handler = function(Exception $exception)
{
    //print $exception;
};

set_exception_handler($handler);

/**
 * Register the PHP error handler. All PHP errors will fall into this
 * handler, which will convert the error into an ErrorException object
 * and pass the exception into the common exception handler.
 *
 * After all, there should never be any errors in our application. If
 * there are then we need to know about them and fix them - not ignore
 * them.
 *
 * Notice, this function will ignore the error if it is less than the
 * current error reporting level.
 */
set_error_handler(function($code, $error, $file, $line) use ($handler)
{
    if((error_reporting() & $code) === 0) return TRUE;

    $handler(new ErrorException($error, $code, 0, $file, $line));
});

/**
 * Register the PHP shutdown handler. This function will be called
 * at the end of the PHP script or on a fatal PHP error. If an error
 * has occured, we will convert it to an ErrorException and pass it
 * to the common exception handler for the framework.
 */
register_shutdown_function(function() use ($handler)
{
    if($error = error_get_last())
    {
        extract($error, EXTR_SKIP);
        $handler(new ErrorException($message, $type, 0, $file, $line));
    }
});


/**
 * Setting the PHP error reporting level to -1 essentially forces PHP to
 * report every error, and is guranteed to show every error on future
 * versions of PHP. This will insure that our handlers above are
 * notified about everything.
 */
error_reporting(-1);

/**
 * At the same time we want to disable PHP's default error display since
 * we are now using our own.
 */
ini_set('display_errors', 'Off');

答案 1 :(得分:2)

不。 幸运的是没有办法做到这一点

答案 2 :(得分:2)

这只是个坏主意。我只是希望你不理解Exceptions是如何工作的,而你并不是这个问题的意思。

首先,当异常传播到主脚本(实际上是异常)并且你的脚本完成后,调用设置异常处理程序... Exception handler

  

如果未在try / catch块中捕获异常,则设置默认异常处理程序。 调用exception_handler后,执行将停止

你应该使用Xeoncross suggesting的内容,但我认为你的调用函数/方法存在问题,因为你可以这样做:

class Clazz {

    private static $exceptions;

    public static function foo(array $exceptions) {
        set_exception_handler(array(__CLASS__, "exception_handler"));
        self::$exceptions = $exceptions;
        try {
            throw new RandomException;
        } catch( Exception $e){
            self::exception_handler( $exception);
        }
        echo "I need this to be printed!";
    }

    public static function exception_handler(Exception $exception) {
    }
}

答案 3 :(得分:0)

通常,这是一个坏主意,因为抛出异常的代码期望任何后续代码都不会被执行,我想这就是为什么它没有在php中实现的原因。

但也许这可能有助于做你想做的事情:

function try_throw($exception) {
    if (!Clazz::exception_handler($exception))
        throw($exception);

}

class Clazz {

    private static $exceptions;

    public static function foo(array $exceptions) {
        set_exception_handler(array(__CLASS__, "exception_handler"));
        self::$exceptions = $exceptions;
        try_throw(new RandomException);
        echo "I need this to be printed!";
    }

    public static function exception_handler($exception) {
        // process the exception in my way...
        // if $exception in self::$exceptions than 1, else 2, fi
        return true;
        // continue in some way, like it has never happenned
        // to instead throw the exception the normal way
        return false;
    }

}