PHP错误处理的宏大、统一理论

2022-08-30 18:21:37

又名,寻求通用错误处理程序(ΟΚ用于商业用途)

我怀疑我是最好的PHP程序员,所以,虽然我有自己的通用错误处理程序,我想知道其他人做了什么,是否有“最佳”(抱歉,如果这听起来很主观 - 我只想画出一般方法(但即使是“最佳实践”标签也已从SO中删除))。set_error_handler()

为了客观起见,我认为这是需要的。如果我错了,请纠正我,如果你同意,请给我指出一些好的代码。

  • 我想捕获尽可能多的信息 - 而不知道错误是什么。

  • 因此,例如,转储调用堆栈是有意义的。

  • 和 和 和 。$_GET$_POST$_SESSION

  • 我希望调用堆栈和全局打印得很漂亮

  • 我想要一些“纯文本”布局,而不是CSS和花哨的JS来扩展/折叠信息。我的用户可能必须剪切/粘贴到电子邮件中,甚至打印出来和传真。

  • 我希望能够添加我自己设计的标头,最好是作为参数,但如果需要,我可以破解代码。标头可能包括程序版本,时间戳等(并且在我的情况下,我有一个审核跟踪,因此我可以包括用户导致崩溃的最后几个操作)。

  • 有些用户可能允许我的代码自动通过电子邮件发送报告,有些用户可能希望预览它,他们通过电子邮件发送它,有些用户可能不希望我发送电子邮件。


答案 1

我建议走“例外”的方式。

当出现用户错误时,抛出异常,您可以将php错误转换为异常,如下所示:

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

尽管这种行为在OOP环境中效果最好。如果您没有单个入口点(如前置控制器),则还可能发现以下情况的松散异常:

function myException($exception)
{
    echo "<b>Exception:</b> " , $exception->getMessage();
}

set_exception_handler('myException');

带有异常的简单调试有点像这样:

function parseException($e) {
    $result = 'Exception: "';
    $result .= $e->getMessage();
    $trace = $e->getTrace();
    foreach (range(0, 10) as $i) {
        $result .= '" @ ';
        if (!isset($trace[$i])) {
            break;
        }
        if (isset($trace[$i]['class'])) {
            $result .= $trace[$i]['class'];
            $result .= '->';
        }
        $result .= $trace[$i]['function'];
        $result .= '(); ';
        $result .= $e->getFile() . ':' . $e->getLine() . "\n\n";
    }

    return $result;
}

从那里评估全球等是在公园里散步。您可能会从 Symfony Framework Debug 工具栏中寻找灵感,它提供了许多这样的请求。


答案 2

我不敢相信这还没有被建议。

在我的公司,我们只使用自定义错误处理程序。错误处理程序将编译一个调试消息,其中包含:Exceptions

  • 获取、发布、COOKIE、会话、全局
  • 跟踪
  • 错误消息(异常或警告中的消息,是的,您还应该捕获警告,甚至是 STRICTness 错误)。

然后将消息发送到监视服务器,如果失败,它将尝试向我们发送电子邮件,失败,它将尝试记录到数据库(如果失败,它将记录到文件)。如果错误是无法保证输出的“致命”错误,则可以选择抛出500标头并打印默认的“oops”消息。

我建议您始终自动报告所有错误。您不想知道的唯一错误是由用户错误输入引起的错误。在这种情况下,错误应该以某种方式呈现给用户。我发现,对于每个异常,您都可以确定这是系统中的错误还是用户的错误。例如:链接到一个页面,然后删除该页面(这将导致404)。您不想知道404,但您的客户想知道。

您始终想知道所有错误的原因很简单。如果您的系统有一个错误,除非您遇到自己,或者您的客户报告它(他们几乎从不这样做),否则您将不知道它。我们曾经有一个擅长隐藏所有错误的系统,而且超级错误。我们开始暴露所有错误,两年后,这是一个非常稳定的应用程序。

此外。您可以使用一个技巧来捕获讨厌的致命错误。您可以使用 来注册一个函数,该函数将始终在 PHP 脚本完成后运行。然后,您可以使用 来检查致命错误。然后,您可以重复上述步骤,使您了解错误。这有效,我一直在使用它。register_shutdown_handlererror_get_last

四舍五入。无论为错误报告选择什么,都与应用程序用户将看到的内容无关。您可以选择向他提供错误报告,甚至可以在此时向他寻求反馈。但大多数时候,您的系统中只有一个错误,因此用户实际上无法对其进行太多操作。


推荐