获取有关500错误的表单数据

Jas*_*sky 9 php iis internal-server-error

当我们的网站遇到内部服务器错误时,我正在尝试收集信息.我们有许多应用程序从未设置正确的错误日志记录,当出现问题时,我们的客户端不会向我们提供最佳信息.我想做的是,当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>
Run Code Online (Sandbox Code Playgroud)

在那个页面上,我只是var_dump-ing $ _POST和$ _GET,看看这些内容是否有任何内容进入错误页面,但事实并非如此.我对500错误的目标是:

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

有没有办法收集这些数据并让自定义错误页面看到它?

error.php:

switch($ErrorCode){
    case '500':
         var_dump($_REQUEST, $_POST, $_GET);
         echo "internal server error";
         break;
}
Run Code Online (Sandbox Code Playgroud)

在所有情况下,$ _POST都是空的,即使我提交了一个表单来获取此错误并且$ _GET包含此内容(这是有道理的):

array(2) {
  ["code"]=>
  string(3) "500"
  ["500;http://icom-sbs/test_php"]=>
  string(0) ""
}
Run Code Online (Sandbox Code Playgroud)

4/19更新

我玩了一些想法,主要是在会话变量中存储有用的数据.我试图将一些表单数据存储在测试页面上的会话变量中,该变量会产生错误,但它永远不会进入会话.看起来服务器检测到页面上会发生错误,因此它甚至不会在页面上执行任何代码并立即执行错误页面.

s3m*_*m3n 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');
Run Code Online (Sandbox Code Playgroud)

简单的测试用例:

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

这是我从示例中使用 handle_fatal 得到的结果:

[FATAL] Class 'Dupa' not found in /var/www/index.php:22
GET:
Array ( [page] => dupa )
POST:
Array ( [subpage] => 1 ) 
Run Code Online (Sandbox Code Playgroud)

毕竟,您应该知道捕获此类错误并不总是最好的主意,您应该小心对待。