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


Trying to use a global exception handler in PHP to handle various toplevel exceptions in a unified manner

请考虑以下代码:

<?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();
?>

我正在尝试做的是通过简单地设置全局异常处理程序,而无需编写任何样板代码(每个文件中都存在的页眉和页脚除外),以统一的方式跨各种文件处理各种类型的异常。

问题是,当引发的异常类型未由全局异常处理程序处理并且我想重新抛出异常时,堆栈跟踪会丢失,这是使用 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

提前感谢!

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

将代码更改为

function global_exception_handler($exception = NULL)

或将说明添加到

throw new Exception('Testing here...');