捕获Server运行期致命错误

Server运行期一旦发生致命错误,那客户端连接将无法得到回应。如Web服务器,如果有致命错误应当向客户端发送Http 500 错误信息。

在PHP中可以通过register_shutdown_function + error_get_last 2个函数来捕获致命错误,并将错误信息发送给客户端连接。具体代码示例如下:

  1. register_shutdown_function('handleFatal');
  2. function handleFatal()
  3. {
  4. $error = error_get_last();
  5. if (isset($error['type']))
  6. {
  7. switch ($error['type'])
  8. {
  9. case E_ERROR :
  10. case E_PARSE :
  11. case E_CORE_ERROR :
  12. case E_COMPILE_ERROR :
  13. $message = $error['message'];
  14. $file = $error['file'];
  15. $line = $error['line'];
  16. $log = "$message ($file:$line)\nStack trace:\n";
  17. $trace = debug_backtrace();
  18. foreach ($trace as $i => $t)
  19. {
  20. if (!isset($t['file']))
  21. {
  22. $t['file'] = 'unknown';
  23. }
  24. if (!isset($t['line']))
  25. {
  26. $t['line'] = 0;
  27. }
  28. if (!isset($t['function']))
  29. {
  30. $t['function'] = 'unknown';
  31. }
  32. $log .= "#$i {$t['file']}({$t['line']}): ";
  33. if (isset($t['object']) and is_object($t['object']))
  34. {
  35. $log .= get_class($t['object']) . '->';
  36. }
  37. $log .= "{$t['function']}()\n";
  38. }
  39. if (isset($_SERVER['REQUEST_URI']))
  40. {
  41. $log .= '[QUERY] ' . $_SERVER['REQUEST_URI'];
  42. }
  43. error_log($log);
  44. $serv->send($this->currentFd, $log);
  45. default:
  46. break;
  47. }
  48. }
  49. }