获取500错误时的表单数据

10

我正在尝试收集有关我们网站遇到内部服务器错误时的信息。我们有许多应用程序从未设置正确的错误日志记录,当问题发生时,我们的客户无法提供最好的可用信息。我的目标是:当出现500错误时,我想要收集有关问题发生位置的数据,例如:

  • 用户所在页面
  • 与该页面相关的任何数据(例如 $_GET、$_POST 等)

我已经在我们的服务器(IIS 7)上设置了自定义错误页面,并使用以下配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors errorMode="Custom">
            <remove statusCode="500" />
            <error statusCode="500" path="/error.php?code=500" responseMode="ExecuteURL" />
        </httpErrors>
    </system.webServer>
</configuration>

在那个页面上,我只是使用var_dump函数打印$_POST和$_GET以查看是否有任何信息传递到错误页面,但没有。我的目标是在出现500错误时:

  • 收集有关页面/用户在错误发生时的数据
  • 向支持团队发送包含收集数据的问题邮件

是否有任何方法可以收集该数据并使自定义错误页面看到它?

error.php:

switch($ErrorCode){
    case '500':
         var_dump($_REQUEST, $_POST, $_GET);
         echo "internal server error";
         break;
}
在所有情况下,即使我提交了一个表单来获取此错误,$_POST仍然为空,而$_GET包含了这个(这是有道理的):
array(2) {
  ["code"]=>
  string(3) "500"
  ["500;http://icom-sbs/test_php"]=>
  string(0) ""
}

4/19 更新

我尝试了一些想法,主要是将有用的数据存储在会话变量中。我试图在测试页面上将一些表单数据存储在会话变量中,但它从未进入会话。似乎服务器检测到页面上会出现错误,因此它甚至不执行页面上的任何代码,并立即执行错误页面。


你能发一下error.php文件中的代码吗? - pilsetnieks
代码和页面响应已添加。 - Jason Kaczmarsky
也许这会有所帮助:https://dev59.com/O0fRa4cB1Zd3GeqP7DOA - Hermann Stephane Ntsamo
4个回答

2
如果您的服务器开始解释php文件,然后出现500错误,这意味着您的代码发生了一些致命错误。可能是任何问题,从简单的拼写错误到执行时间限制达到。
在PHP中捕获致命错误的最佳且唯一的方法是使用register_shutdown_function。您应该在工作文件的顶部定义它:
function handle_fatal() {
    $error = error_get_last(); // PHP 5.2+
    if($error !== NULL){
        $error_landing_page = '[FATAL] '.$error['message'].' in '.$error['file'].':'.$error['line'] . '<br/>GET:<br/>' . print_r($_GET, true) . '<br/>POST:<br/>' . print_r($_POST, true);
        // mail here if you need that and include $_GET, $_POST variables - this will be the last state before error occurred
        exit($error_landing_page);
    }
}

register_shutdown_function('handle_fatal');

简单测试案例:
// put handling function at the very beginning
function handle_fatal() {/*...*/}
register_shutdown_function('handle_fatal');

// now do some logic
if($_GET['page'] == 'dupa'){
    $_POST['subpage'] = 1; // more and more logic
    $obj = new Dupa(); // class not found exception
}

这是我从例子中使用handle_fatal函数获得的结果:
[FATAL] Class 'Dupa' not found in /var/www/index.php:22
GET:
Array ( [page] => dupa )
POST:
Array ( [subpage] => 1 ) 

毕竟,您应该知道捕捉这种错误并不总是最好的想法,您应该小心谨慎。

这看起来正是我正在寻找的。谢谢你提供的潜在问题,我会记住它们。 - Jason Kaczmarsky

2
我认为你需要在服务器级别而不是PHP级别记录详细信息,因为当发生500内部错误时,PHP甚至可能没有初始化。如果你使用的是Apache,你可以查看。

http://httpd.apache.org/docs/1.3/mod/mod_log_config.html#logformat

错误日志肯定会提供请求的URL、远程地址和GET参数(查询字符串)。但是我不确定POST数据。也许您可以更改日志格式,在某个级别上转储整个标头和原始数据。
但是我确定,在PHP级别记录时,当服务器实际放弃并且PHP不起作用时,会跳过某些时间...

0

检查$_SERVER数组是否有任何有趣的内容。

我进行了一些研究,如果您使用的是ASP,您将能够在Server.GetLastError中获取错误详细信息,这让我相信IIS可能会通过$_SERVER数组传递信息。


我正在使用PHP。我可以通过REQUEST_URI获取他们所在的页面,但没有其他我需要的有用数据。 - Jason Kaczmarsky
我知道,这就是为什么我提到IIS会将信息交给ASP,所以它可能会使用$_SERVER数组将信息传递给PHP。 - akirk

0

我相信你可以在PHP中设置自定义错误处理程序。困难的是,有些错误可能会导致PHP崩溃并返回500而不触发错误处理程序。好处是,它应该很容易在整个网站范围内实现,而不需要进行大量更改。

http://www.php.net/manual/en/function.set-error-handler.php

你应该能够在 $_SERVER 全局变量中找到大部分相关信息。你也可以查看 debug_backtrace 函数,它会给你一个堆栈跟踪。

http://php.net/manual/en/function.debug-backtrace.php

祝你好运


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接