使用错误异常处理程序和关闭序列在没有堆栈帧的情况下防止异常

2024-01-29

这一周我遇到了一些小问题。前面的错误消息是关于:

[2012 年 12 月 30 日 15:19:32] PHP 致命错误:在第 0 行的 Unknown 中没有堆栈帧的情况下抛出异常

我认为这是因为我的错误处理程序(详细信息见下文)正在将任何错误转换为异常。如果没有堆栈框架,我可能应该阻止这种情况。

有没有一种简单的方法可以找出PHP中是否有堆栈框架?

Details:

在我的一个网站上,我运行了一个错误处理程序,它将每个错误转换为异常,这是常见的ErrorException http://php.net/ErrorException准确地说。

我前一段时间引入了它,因为该网站主要是遗留代码,我希望任何问题都会导致异常,我最终可以以简化的方式“捕获”异常处理程序并停止请求。

我将其放入它自己的类中,注册处理程序,同时打开一个输出缓冲区以捕获输出,直到引发异常。基本上代码是这样的:

// register output buffering
$r = ob_start(array($this, 'handleBuffer'));

// register error handler       
$this->_originalErrorHandler = set_error_handler(array($this, 'handleError'));

// register exception handler
$this->_originalExceptionHandler = set_exception_handler(array($this, 'handleException'));

这一切都很好,直到我决定添加另一个输出缓冲类到混合中。只是一个捕获所有输出,然后可以在网站上进行一些“后期制作”,包括检查 HTML 问题(是的,这都是一些遗留问题,所以实际上这有点像鸭子胶带,我知道)。顺便说一句,这也非常有效。但是当我在新组件中犯了错误时却没有:

[2012 年 12 月 30 日 15:19:32] PHP 致命错误:在第 0 行的 Unknown 中没有堆栈帧的情况下抛出异常

这基本上是我的问题。有没有一种简单的方法可以防止出现这些错误?我有点知道为什么会出现这个错误,但我不太确定,所以我很难真正规避这个问题。我试图释放新的输出缓冲区before脚本进入新的关闭阶段,因为我认为这会导致这种情况。但这并没有成功。


您的问题表明您正在使用EOL (生命尽头) 版本的 PHP(特别是 PHP

这可能是由于几个不同的原因造成的。一些最常见的如下:

  1. 您从错误处理程序或异常处理程序内部引发了异常。
  2. 您从析构函数内部引发了异常。
  3. 您从回调内部引发了异常(如输出缓冲回调函数)。

这是一个示例,演示了您在某些情况下的问题......

function myErrorHandler($errno, $errstr, $errfile, $errline)
{
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}

function myExceptionHandler($exception) {
    echo "We got an exception with message: '{$exception->getMessage()}'";
}

function myCallBack($contents) {
    trigger_error('ohnoes!'); // You can't throw an error from the output buffer callback function in older versions of PHP < 5.3
}

class Foo {
    public function __destruct() {
        trigger_error('ohnoes!'); // You can't throw an error from a destructor in older versions of PHP < 5.3
    }
}

set_error_handler('myErrorHandler');
set_exception_handler('myExceptionHandler');

上面的代码会导致您看到您在此处描述的致命错误......

ob_start("myCallBack");

... 和这里...

$foo = new foo;

此问题已在 PHP >= 5.3.0 中得到修复,因此如果您使用的是最新版本的 PHP,则不应看到此问题。

最简单的修复方法是升级 PHP。如果这不是一个选择,您必须考虑这些事实,即您不能在 PHP 不希望抛出异常的地方抛出异常(在回调函数、错误处理程序、异常处理程序等中......实际上都被认为是PHP 回调)。

另一件事是你不应该以这种方式将每个错误都变成异常。如果您正在做的事情正如我提供的代码所示(即从错误处理程序内部抛出异常 - 从而将每个错误变成异常),那么您将导致自己a lot的痛苦,而且几乎没有任何好处。 PHP 错误不应该被处理。它们的目的是告知客户一个问题(客户端是编写 PHP 代码的人),或潜在的问题。处理错误本身并不像将每个错误都转换为异常然后处理该异常那么简单,因为并非每个错误都应该是异常的。例如,E_NOTICE 级别的错误在异常处理中没有地位。它们主要用于通知您可能存在错误,而不是您的代码一定存在错误,更不用说大多数错误甚至无法在用户空间代码中轻松处理(它们大多需要重新分解代码本身)。我强烈建议反对这种糟糕的做法.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用错误异常处理程序和关闭序列在没有堆栈帧的情况下防止异常 的相关文章

随机推荐