This RFC proposes to extend or change the way that backtraces that come with Exception works, currently it is impossible to obtain the 'object' value in backtrace frames from the \Exception::getTrace() method/\Exception::$trace property, like you would with the \debug[_print]_backtrace() functions (with the $options parameter).
Currently if an exception is thrown within an class instance, the $this cannot be obtained by using the exception's provided backtrace for debuggers that does more extensive analytics in userland code.
This RFC proposes two solutions:
Always provide the 'object' index for backtrace frames, this means that the exception object will be a bit heavier as it needs to hold a reference to the callee's $this object, for each frame. This means that both the return value of the property and method will always carry the 'object' index when available.
By adding a parameter to \Exception::getTrace() to pass debug options, and always keep \Exception::$trace on pair with the default of \debug[_print]_backtrace(). Internally this means we may need to save the execution state to make this possible, and I would like some input on this from Engine developers to make come up with an implementation that suits this if possible. This means only the returned value of \Exception::getTrace() will have the 'object' index if specified, the property will remain the same as it currently is.
If either of the solutions is accepted, then the following example will now be possible:
Solution 1
<?php class Test { public function error() { throw new Exception('This is a test'); } } try { (new Test)->error(); } catch(Exception $e) { // "Test" echo(get_class($e->getTrace()[0]['object'])); } ?>
Solution 2
<?php class Test { public function error() { throw new Exception('This is a test'); } } try { (new Test)->error(); } catch(Exception $e) { // "Test" echo(get_class($e->getTrace(DEBUG_BACKTRACE_PROVIDE_OBJECT)[0]['object'])); } ?>
There is no backwards incompatible changes to this RFC.
PHP 7.1
Since this is not a language change, then this RFC requires a majority of 50%+1 to be accepted.
Should this RFC be accepted, then a patch will be provided and committed including tests.