Trying to use a global exception handler in PHP to handle various toplevel exceptions in a unified manner
Please consider the following code:
<?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();
?>
What I'm trying to do is handling various types of exceptions in a unified way across various files by simply setting up a global exception handler without having to write any boilerplate code (except the header and footer includes which are present in 开发者_高级运维every file).
The problem is that when the thrown exception type is not handled by the global exception handler and I want to rethrow the exception, the stack trace gets lost which is a limitation of using set_exception_handler().
I can retrieve the stack trace by using debug_backtrace() but I cannot access its relevant private members to be able to print it appropriately.
This is what the above script produces:
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
Thanks in advance!
Check the comments on http://php.net/manual/de/function.set-exception-handler.php there are several similar issues and solutions there. For your code I see two possible solutions:
Change your code into
function global_exception_handler($exception = NULL)
or add a description to
throw new Exception('Testing here...');
精彩评论