使用自定义关闭处理程序时,防止PHP致命错误追溯输出

前端之家收集整理的这篇文章主要介绍了使用自定义关闭处理程序时,防止PHP致命错误追溯输出前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我必须在处理 PHP错误的理解中缺少某些东西,特别是抑制其输出.当发生致命错误时,我期望我的关机处理程序功能正常处理并终止脚本执行.这样可以预期.但是,我似乎无法阻止PHP输出关于致命错误的信息.

我的PHP.ini文件包含以下指令:

error_reporting = E_ALL | E_STRICT
display_errors = Off

我设置error_reporting来报告所有内容,我使用自定义错误处理程序来抛出异常.我的期望是display_errors = Off将防止显示任何错误消息.

无论如何,当发生致命错误时,会绕过自定义错误处理程序(因为脚本执行立即停止),并且执行关闭处理程序.

现在,关于我的简化代码

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors','Off');

function shutdown_handler()
{
  $err = error_get_last();
  $fatal = array(E_ERROR,E_PARSE,E_CORE_ERROR,E_COMPILE_ERROR);
  if ($err && in_array($err['type'],$fatal)) {
    echo "\n\ntest fatal error output\n\n";
  }
  exit();
}

register_shutdown_function('shutdown_handler');

要测试它,我会生成一个“允许的内存大小耗尽”致命错误,如下所示:

// max out available memory
$data = '';
while(true) {
  $data .= str_repeat('#',PHP_INT_MAX);
}

因为我有display_errors = Off我期望这只产生以下输出(根据关闭处理程序):

test fatal error output

而是我继续接受:

PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 2147483648 bytes) in /home/daniel/mydev/PHP/test0.PHP on line 24
PHP Stack trace:
PHP   1. {main}() /home/daniel/mydev/PHP/test0.PHP:0
PHP   2. str_repeat() /home/daniel/mydev/PHP/test0.PHP:24

test fatal error output

我缺少什么会阻止这个错误跟踪输出

结论

正如@Cthos所说的那样,“E_ERROR和display_errors不能很好地在一起玩”.

E_PARSE也是如此(我假设E_CORE_ERROR / E_COMPILE_ERROR,但是我没有打破我的PHP安装来测试它).我想这是有道理的,PHP会强制错误追溯到STDOUT在这些情况下,因为如果你不可能永远不知道/为什么事情出错了.

所以在这种情况下的解决办法是:

> as @Cthos建议,使用PHP.ini:error_reporting =(E_ALL&〜E_ERROR)或在运行时使用error_reporting(E_ALL&〜E_ERROR)静音E_ERROR通知;
>更新关闭处理程序以检查最后一个错误是否为E_ERROR类型,如果是,则执行相应的操作.

至于像E_PARSE,E_CORE_ERROR等其他致命的事情,你只需要确保你的代码是正确的,你的PHP可以工作.如果您尝试沉默E_PARSE错误并在关闭功能中处理它们将无法正常工作,因为解析错误会阻止PHP发生这种变化.

所以,更新/工作的关机处理程序如下所示:

error_reporting(E_ALL & ~ E_ERROR);

function shutdown_handler()
{
  $err = error_get_last();
  if ($err && $err['type'] == E_ERROR) {
    $msg = 'PHP Fatal Error: '.$err['message'].' in '.$err['file'].
      ' on line '.$err['line'];
    echo $msg,PHP_EOL;
  }
  exit();
}
不需要的错误信息是由于错误日志记录配置( log_errorserror_log)而完全独立于display_errors配置.从命令行运行脚本时,默认的PHP.ini配置会将错误详细信息记录到stderr.在Apache下,它们显示/etc/httpd/logs/error_log.

查看PHP源的main.c中的php_error_cb函数.特别地,第1056行清楚地表明,任何格式为“PHP%s:%s在%s行%d”上的消息都是由于错误记录配置(由于display_errors的错误信息将不会有“PHP:”)字首).

猜你在找的PHP相关文章