在异常处理程序中抛出异常

我有一个带有异常处理程序的脚本。 在异常之后脚本退出之前,此异常处理程序会清除一些连接。</ p>

我想从此异常处理程序中重新抛出异常,以便由PHP自己处理 最后的异常处理程序,其中错误被写入PHP的错误日志,或者在PHP.ini中配置的默认值。</ p>

不幸的是,这似乎不太可能 ,如下所述:</ p>

http://www.php.net/manual/en/function.set-exception-handler.php#68712 </ p>


会导致 致命错误:抛出没有堆栈帧的异常</ p>
</ blockquote>

是否有另一种方法将错误冒充堆栈,以便PHP在异常处理程序完成后处理它 up?</ p>
</ div>

展开原文

原文

I have a script with an exception handler. This exception handler cleans up a couple connections, prior to the script exiting after an exception.

I would like to re-throw the exception from this exception handler so that it is handled by PHP's own last-resort exception handler, where the error is written to PHP's error log, or whatever the default is, as configured in PHP.ini.

Unfortunately, this doesn't seem like a possibility, as outlined here:

http://www.php.net/manual/en/function.set-exception-handler.php#68712

Will cause a Fatal error: Exception thrown without a stack frame

Is there another way to bubble the error up the stack so that PHP handles it after my exception handler is done cleaning up?

doutuoji8418
doutuoji8418 我以前见过这个(并建议恢复错误处理程序)但我现在无法重现!此问题是否部分适用于PHP/.ini设置的版本?
接近 9 年之前 回复
dongyou5098
dongyou5098 为什么不直接从处理程序中抛出异常?如果你知道如何,它会工作。它会触发你正在寻找的PHP最后的处理程序。
接近 9 年之前 回复
doujiaohuo1096
doujiaohuo1096 使用自定义异常处理程序仍将触发致命错误,从而记录错误。
接近 9 年之前 回复

5个回答

You can not re-throw from the exception handler, however, there are other places you can. For example you can de-couple the re-throw from the handler by encapsulating things into a class of it's own and then use the __destruct() function (PHP 5.3, Demo):

<?php

class ExceptionHandler
{
    private $rethrow;
    public function __construct()
    {
        set_exception_handler(array($this, 'handler'));
    }
    public function handler($exception)
    {
        echo  "cleaning up.
";
        $this->rethrow = $exception;
    }
    public function __destruct()
    {
        if ($this->rethrow) throw $this->rethrow;
    }
}

$handler = new ExceptionHandler;

throw new Exception();

Put this into my error log:

[29-Oct-2011 xx:32:25] PHP Fatal error: Uncaught exception 'Exception' in /.../test-exception.php:23
Stack trace:
#0 {main}
thrown in /.../test-exception.php on line 23
doushi7314
doushi7314 同意,谢谢。
接近 9 年之前 回复
dpvr49226
dpvr49226 嘿布拉德,谢谢你的接受。 我喜欢这个“解决方法”,而不是关于php.net上的用户注释的建议,以创建自己的错误日志条目。 为什么重新发明轮子? 我也尝试过注册关闭功能,但这里我更喜欢这个。
接近 9 年之前 回复
duandi8838
duandi8838 谢谢@hakre,您的解决方案有效。 比我希望的更多的解决方法,但我明白为什么这是必要的。
接近 9 年之前 回复
douwen3836
douwen3836 请参阅,这与__destruct有些相关:如何确定PHP脚本处于终止阶段?
接近 9 年之前 回复




将导致致命错误:抛出没有堆栈帧的异常</ p>
</ blockquote> \ n

此错误意味着您的异常是从不属于脚本的代码中抛出的(据PHP所知)。 此类代码的示例包括使用set_exception_handler()设置的自定义异常处理程序以及任何类析构函数方法。 除了不从这样的代码中抛出异常,别无选择。</ p>

如果你想要PHP本机错误处理,我建议你调用 trigger_error()。 如果您没有自定义错误处理程序并且使用了合适的错误类型,它应该记录错误。 例如,E_USER_ERROR应该没问题。</ p>
</ div>

展开原文

原文

Will cause a Fatal error: Exception thrown without a stack frame

This error means that your exception is thrown from a code that is not part of the script (as far as PHP knows). Examples of such code include custom exception handler set with set_exception_handler() and any class destructor method. There's no choice but to NOT throw an exception from such a code.

If you want PHP native error handling, I'd suggest you to call trigger_error() instead. It should log the error if you don't have custom error handler and you use suitable error type. For example, E_USER_ERROR should be fine.

doutan2228
doutan2228 hakre:是的,它似乎与PHP 5.3+一起使用。 很好找!
接近 9 年之前 回复
donglu3087
donglu3087 Mikko,看起来我的答案需要PHP 5.3。 另请参阅codepad.viper-7.com/jamrqP
接近 9 年之前 回复
dspv70887
dspv70887 hakre:只是尝试它(从自定义异常处理程序或类析构函数方法中抛出任何东西) - 你会发现它不起作用。 如果您使用xdebug则无关紧要。
接近 9 年之前 回复
duanluo9369
duanluo9369 或者只是再次抛出异常,这取决于配置将给出正确的回溯。
接近 9 年之前 回复

Just catch the exception and log the message yourself, then rethrow.

try {
    $foo->doSomethingToCauseException();
} catch (Exception $e) {
    error_log($e->getMessage());
    throw $e;
}

If you bubble up to the top and PHP is unable to handle, it will result in uncaught exception.

drccfl9407
drccfl9407 我知道了。 我对此也很好奇。 根据我的经验,PHP处理异常的唯一方法是使页面爆炸,大声笑。
大约 9 年之前 回复
dongliang1941
dongliang1941 一个未被捕获的例外对我来说没问题。 我想把所有的泡沫都吹到顶端。 我现在正在自行记录错误(使用您描述的确切方法),但为了保持一致性,我宁愿让PHP处理它。
大约 9 年之前 回复

Just rethrow the exception as a RunTimeException and it will keep the stacktrace :)

try {
    // bad exception throwing code
} catch (Exception $e) {
    throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}



来自 http://www.php.net/manual/en/function.set-exception-handler.php#88082
i阅读:
另一个解决方案是恢复 异常处理程序开头的错误处理程序。

你试过吗?</ p>
</ div>

展开原文

原文

From http://www.php.net/manual/en/function.set-exception-handler.php#88082 i read: Another solution is to restore the error handler at the beginning of the exception handler. Have you tried it?

douoyou3348
douoyou3348 对不起,这不起作用。 restore_exception_handler()在异常中无效。
接近 9 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐