当我们的网站遇到内部服务器错误时,我正在尝试收集信息。我们有许多应用程序从未设置正确的错误日志记录,当出现问题时,我们的客户端不会给我们提供最好的信息。我想做的是,当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更新
我尝试了一些想法,主要的一个是在会话变量中存储有用的数据。我试图将一些表单数据存储在给出错误的测试页面上的会话变量中,但它从未进入会话。似乎服务器检测到页面上将发生错误,因此它甚至不会执行页面上的任何代码,而是立即执行错误页面。
如果您的服务器开始解释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 )
毕竟,您应该知道捕获此类错误并不总是最好的主意,您应该小心。
我认为您需要在服务器级别而不是php级别记录详细信息,因为php在发生500内部错误时甚至可能不会初始化。如果你使用的是apache,你可以查看
http://httpd.apache.org/docs/1.3/mod/mod_log_config.html logformat
错误日志肯定会提供请求url,远程地址和get参数(查询字符串)。但我不确定后的数据。也许你可以对日志格式进行一些更改,以便在某个级别转储整个头和原始数据。
但是我确信php级别的日志记录在某些时候会跳过,当服务器实际上放弃php不踢…
检查$_SERVER
数组是否有感兴趣的内容
我研究了一下,如果你使用ASP,你可以在服务器中获得错误细节。GetLastError使我相信IIS可能通过$_SERVER
数组传递信息
我相信您可以在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 好运