尝试在PHP中使用全局异常处理程序以统一的方式处理各种顶级异常

Lás*_*nda 2 php global exception handler

请考虑以下代码:

<?php

class MyException extends Exception {}

function global_exception_handler($exception)
{
    switch (get_class($exception)) {
    case 'MyException':
        print "I am being handled in a unified way.\n";
        break;
    default:
        $backtrace = debug_backtrace();
        $exception_trace_object = $backtrace[0]['args'][0];
        var_dump($exception_trace_object);
        print "----\n";
        $reflected_exception_trace_object = new ReflectionObject($exception_trace_object);
        $reflected_trace_property = $reflected_exception_trace_object->getProperty('trace');
        $reflected_trace_property->setAccessible(true);
        var_dump($reflected_trace_property);
        print "----\n";

        // NOT WORKING, I STUCK HERE.
        var_dump($reflected_trace_property->getValue($reflected_trace_property));

        throw $exception;
    }
}

set_exception_handler('global_exception_handler');

function function1()
{
    function2();
}

function function2()
{
    function3();
}

function function3()
{
    throw new Exception();
}

function1();

?>
Run Code Online (Sandbox Code Playgroud)

我想要做的是通过简单地设置一个全局异常处理程序,而不必编写任何样板代码(除了包含每个文件中的页眉和页脚)之外的各种文件,以统一的方式处理各种类型的异常.

问题是当全局异常处理程序没有处理抛出的异常类型并且我想重新抛出异常时,堆栈跟踪会丢失,这是使用set_exception_handler()的限制.

我可以使用debug_backtrace()检索堆栈跟踪,但我无法访问其相关的私有成员以便能够正确打印它.

这就是上面脚本产生的:

object(Exception)#1 (7) {
  ["message":protected]=>
  string(0) ""
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(28) "/home/laci/download/test.php"
  ["line":protected]=>
  int(42)
  ["trace":"Exception":private]=>
  array(3) {
    [0]=>
    array(4) {
      ["file"]=>
      string(28) "/home/laci/download/test.php"
      ["line"]=>
      int(37)
      ["function"]=>
      string(9) "function3"
      ["args"]=>
      array(0) {
      }
    }
    [1]=>
    array(4) {
      ["file"]=>
      string(28) "/home/laci/download/test.php"
      ["line"]=>
      int(32)
      ["function"]=>
      string(9) "function2"
      ["args"]=>
      array(0) {
      }
    }
    [2]=>
    array(4) {
      ["file"]=>
      string(28) "/home/laci/download/test.php"
      ["line"]=>
      int(45)
      ["function"]=>
      string(9) "function1"
      ["args"]=>
      array(0) {
      }
    }
  }
  ["previous":"Exception":private]=>
  NULL
}
----
object(ReflectionProperty)#3 (2) {
  ["name"]=>
  string(5) "trace"
  ["class"]=>
  string(9) "Exception"
}
----
NULL

Fatal error: Exception thrown without a stack frame in Unknown on line 0
Run Code Online (Sandbox Code Playgroud)

提前致谢!

pow*_*tac 5

查看http://php.net/manual/de/function.set-exception-handler.php上的评论,其中有几个类似的问题和解决方案.对于您的代码,我看到两种可能的解决方

将您的代码更改为

function global_exception_handler($exception = NULL)
Run Code Online (Sandbox Code Playgroud)

或添加说明

throw new Exception('Testing here...');
Run Code Online (Sandbox Code Playgroud)

  • powtac,你是男人!参考页面上的pinkgothic示例正是我一直在寻找的.非常感谢! (2认同)