set_error_handler无法正常工作

时间:2020-03-05 18:45:36  来源:igfitidea点击:

我正在飞跃:我的php脚本都会全部失败!

至少那是我所希望的...

我不想(实际上)在try ... catch语句中包装每一行,所以我认为最好的选择是为文件的开头创建一个自定义错误处理程序。

我正在练习页面上对其进行测试:

function customError($level,$message,$file,$line,$context) {
    echo "Sorry, an error has occured on line $line.<br />";
    echo "The function that caused the error says $message.<br />";
    die();
}

set_error_handler("customError");

echo($imAFakeVariable);

这工作正常,返回:

Sorry, an error has occured on line 17. The function that caused the
  error says Undefined variable: imAFakeVariable.

但是,此设置不适用于未定义的功能。

function customError($level,$message,$file,$line,$context) {
    echo "Sorry, an error has occured on line $line.<br />";
    echo "The function that caused the error says $message.<br />";
    die();
}

set_error_handler("customError");

imAFakeFunction();

这将返回:

Fatal error: Call to undefined function: imafakefunction() in
  /Library/WebServer/Documents/experimental/errorhandle.php on line 17

为什么我的自定义错误处理程序无法捕获未定义的函数?这还会引起其他问题吗?

解决方案

回答

Why isn't my custom error handler catching undefinedd functions? Are there other problems that this will cause?

猜测一下,我想说未定义的函数错误会通过与其他错误类型不同的执行路径传播。也许PHP设计师可以告诉我们更多信息,除非我怀疑PHP是否以任何方式设计。

如果我们希望自己的脚本在仍然以PHP风格编写的同时仍然无法正常运行,请尝试将整个页面放在一个函数中,然后在try..catch块中调用它。

回答

在文档中(添加了重点):

The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

调用未定义的函数会触发E_ERROR,因此错误回调(或者与此相关的异常处理程序)无法对其进行处理。我们所能做的就是将error_reporting设置为0。

PS,如果我们要滚动自己的错误处理程序,则应注意正确处理@运算符。从文档(添加重点):

It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator.

回答

set_error_handler设计用于处理以下代码的错误:E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE`。这是因为" set_error_handler"是一种报告由用户错误函数" trigger_error"引发的错误的方法。

但是,我确实在手册中找到了此评论,可能会对我们有所帮助:

"The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called."
  
  This is not exactly true.  set_error_handler() can't handle them, but ob_start() can handle at least E_ERROR.

<?php

function error_handler($output)
{
    $error = error_get_last();
    $output = "";
    foreach ($error as $info => $string)
        $output .= "{$info}: {$string}\n";
    return $output;
}

ob_start('error_handler');

will_this_undefined_function_raise_an_error();

?>

确实,尽管这些错误应例如以文件形式静默报告。希望项目中不会出现很多" E_PARSE"错误! :-)

至于一般的错误报告,请坚持使用异常(我发现使它们与我的MVC系统配合使用会很有帮助)。我们可以构建一个非常通用的Exception,以通过按钮提供选项,并添加大量描述以使用户知道出了什么问题。