PHP RFC: StackFrame class
- Version: 1.2
- Date: 2020-07-07
- Author: Michał Marcin Brzuchalski, brzuchal@php.net
- Status: Declined
- Target Version: PHP 8.0
- First Published at: http://wiki.php.net/rfc/stack-frame-class
- Implementation: https://github.com/php/php-src/pull/5820
Introduction
The debug_backtrace()
function currently returns stack trace frames as an array of arrays with information about the file, line, class, type, object, args and function name as keys. This RFC proposes to add a debug_backtrace()
alternative which returns an array of objects instead. This reduces memory usage and makes code operating on frames more readable.
Proposal
Introduce new StackFrame
class with static method getTrace()
returning array of StackFrame
object instances.
There are two places where this could be a replacement for retrieving trace in array of arrays way and these are ReflectionGenerator::getTrace()
and Throwable::getTrace()
. These should be a subject of the secondary vote.
StackFrame class
StackFrame
class provides properties which mirrors information from debug_backtrace()
.
There are additional properties and methods which expose additional information:
- property
object_class
exposes object class which is useful when$option
passed withoutDEBUG_BACKTRACE_PROVIDE_OBJECT
flag; - property
closure
exposes a closure within the frame was produced upon.
final class StackFrame implements ArrayAccess { public ?string $file; public ?int $line; public ?string $function; public ?string $class; public ?object $object; public ?string $objectClass; public ?string $type; public ?\Closure $closure; public array $args = []; public static function getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit = 0): array {} }
Example
An example below shows exactly the same portion of information as if it would call debug_backtrace()
instead of StackFrame::getTrace()
.
function frames() { return StackFrame::getTrace(); } $frame = frames()[0]; var_dump([ 'file' => $frame['file'], 'line' => $frame['line'], 'function' => $frame['function'], 'class' => $frame['class'], 'type' => $frame['type'], 'object' => $frame['object'], 'args' => $frame['args'], ]);
Performance
On a test script with 1M recursions to produce huge result results were as above:
StackFrame::getTrace()
execution time was 0.299s and memory usage was only 192.96MB.debug_backtrace()
execution time is 0.333s which is similar but the memory usage was 390.96MB.
Backward Incompatible Changes
If vote decides about changing Exception
trace with array of StackTrace
objects then Exception::getTrace()
method will no longer be a mutable array of arrays with simple keys.
Although a StackFrame
implements ArrayAccess
interface and allow to read all keys in BC manner manipulation on frames will no longer be possible.
Proposed PHP Version(s)
Next PHP 8.0
RFC Impact
To SAPIs
None.
To Existing Extensions
None.
To Opcache
None.
New Constants
None.
Proposed Voting Choices
As this is a change in exception handling mechanism it requires 2/3 accepted.
The vote will be a simple Yes/No for StackFrame
inclusion and second vote a simple Yes/No for exception trace replacement.
Vote
Voting opened 2020-07-21 and closes 2020-08-04.