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

Maw*_*awg 23 php error-handling

又名,寻求通用错误处理程序(商用的ΚΚ)

我怀疑我是最好的PHP程序员,所以,虽然我有自己的通用错误处理程序set_error_handler(),我想知道其他人做了什么,如果有一个"最好"(对不起,如果这听起来主观 - 我只是想绘制一般方法(但即使是"最佳实践"标签也已从SO中移除)).

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

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

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

  • $_GET,$_POST$_SESSION.

  • 我希望调用堆栈和Globals能够打印出来

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

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

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

Are*_*end 28

我建议采用"例外"的方式.

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

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
Run Code Online (Sandbox Code Playgroud)

虽然这种行为在OOP环境中效果最好.如果你没有单一的入口点(比如前控制器),你也可能会遇到松散的异常:

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

set_exception_handler('myException');
Run Code Online (Sandbox Code Playgroud)

使用异常进行简单调试会有点像这样:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • +1表示单一入口点.您应始终拥有尽可能少的入口点. (4认同)

Hal*_*yon 13

我不敢相信这还没有被提出.

在我的公司,我们只使用Exceptions自定义错误处理程序.错误处理程序将使用以下代码编译调试消息:

  • GET,POST,COOKIES,SESSION,GLOBALS
  • 一丝痕迹
  • 错误消息(异常中的消息或警告,是的,您还应该捕获警告,甚至是STRICTness错误).

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

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

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

另外.有一个技巧可以用来捕捉讨厌Fatal Errors.您可以使用register_shutdown_handler注册一个在PHP脚本完成后始终运行的函数.然后您可以error_get_last用来检查致命错误.然后,您可以重复上述步骤以使您知道错误.这是有效的,我一直都在使用它.

四舍五入.无论您选择何种错误报告,都与应用程序的用户将看到的内容无关.你可以选择给他一个错误报告,你甚至可以在那时向他询问反馈.但大多数情况下,系统中只有一个错误,因此用户无法真正做到这一点.

  • 它实际上只是通过HTTP请求调用Web服务.所以它是一个非常活跃的监控系统,它运行良好. (2认同)