PHP : 自定义错误处理程序 - 处理解析和致命错误

如何使用自定义错误处理程序处理解析致命错误?


答案 1

实际上,您可以处理解析和致命错误。确实,您用 set_error_handler() 定义的错误处理程序函数不会被调用。方法是使用register_shutdown_function()定义关机函数。以下是我在网站上所做的工作:

文件前置.php(此文件将自动附加到所有 php 脚本之前)。有关将文件预置到 PHP 的提示,请参阅下文。

set_error_handler("errorHandler");
register_shutdown_function("shutdownHandler");

function errorHandler($error_level, $error_message, $error_file, $error_line, $error_context)
{
$error = "lvl: " . $error_level . " | msg:" . $error_message . " | file:" . $error_file . " | ln:" . $error_line;
switch ($error_level) {
    case E_ERROR:
    case E_CORE_ERROR:
    case E_COMPILE_ERROR:
    case E_PARSE:
        mylog($error, "fatal");
        break;
    case E_USER_ERROR:
    case E_RECOVERABLE_ERROR:
        mylog($error, "error");
        break;
    case E_WARNING:
    case E_CORE_WARNING:
    case E_COMPILE_WARNING:
    case E_USER_WARNING:
        mylog($error, "warn");
        break;
    case E_NOTICE:
    case E_USER_NOTICE:
        mylog($error, "info");
        break;
    case E_STRICT:
        mylog($error, "debug");
        break;
    default:
        mylog($error, "warn");
}
}

function shutdownHandler() //will be called when php script ends.
{
$lasterror = error_get_last();
switch ($lasterror['type'])
{
    case E_ERROR:
    case E_CORE_ERROR:
    case E_COMPILE_ERROR:
    case E_USER_ERROR:
    case E_RECOVERABLE_ERROR:
    case E_CORE_WARNING:
    case E_COMPILE_WARNING:
    case E_PARSE:
        $error = "[SHUTDOWN] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line'];
        mylog($error, "fatal");
}
}

function mylog($error, $errlvl)
{
...do whatever you want...
}

PHP 将调用函数 errorHandler() 如果他在任何脚本中捕获错误。如果错误强制脚本立即关闭,则错误由函数 shutdownHandler() 处理。

这是在我开发的网站上工作。我还没有在生产环境中测试它。但它目前正在捕获我在开发它时发现的所有错误。

我相信存在两次捕获相同错误的风险,每个函数一次。如果我在函数 shutdownHandler() 中处理的错误也被函数 errorHandler() 捕获,则可能会发生这种情况。

待办事项:

1 - 我需要处理一个更好的log()函数来优雅地处理错误。因为我仍在开发中,所以我基本上将错误记录到数据库中,并将其回显到屏幕上。

2 - 为所有MySQL调用实现错误处理。

3 - 为我的javascript代码实现错误处理。

重要提示:

1 - 我在php中使用以下行.ini自动将上述脚本附加到所有php脚本之前:

auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"

它工作得很好。

2 - 我正在记录并解决所有错误,包括E_STRICT错误。我相信开发一个干净的代码。在开发过程中,我的 php.ini 文件具有以下行:

track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0

当我上线时,我会将display_errors更改为0,以降低用户看到丑陋的PHP错误消息的风险。

我希望这可以帮助某人。


答案 2

简单的回答:你不能。请参阅手册

用户定义的函数无法处理以下错误类型:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING以及调用 set_error_handler() 的文件中引发的大多数E_STRICT。

对于所有其他错误,您可以使用set_error_handler()

编辑:

由于似乎有一些关于这个主题的讨论,关于使用,我们应该看看处理的定义:对我来说,处理错误意味着捕获错误并以对用户底层数据(数据库,文件,Web服务等)“好”的方式做出反应。register_shutdown_function

使用时,您无法从调用错误的代码中处理错误,这意味着代码在发生错误时仍将停止工作。但是,您可以向用户显示错误消息而不是白页,但例如,您无法回滚代码在失败之前执行的任何操作。register_shutdown_function


推荐