Extending Exception backtraces to provide 'object'
- Version: 1.0
- Date: 11/04 - 2016
- Author: Kalle Sommer Nielsen kalle@php.net
- Status: Inactive
- First Published at: http://wiki.php.net/rfc/exception_bt_provide_object
Proposal
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:
Solution 1
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.
Solution 2
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.
Example
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'])); } ?>
Backward Incompatible Changes
There is no backwards incompatible changes to this RFC.
Proposed PHP Version
PHP 7.1
Proposed Voting Choices
Since this is not a language change, then this RFC requires a majority of 50%+1 to be accepted.
Patches and Tests
Should this RFC be accepted, then a patch will be provided and committed including tests.