Wednesday, 12 September 2018

Backtracing with PHP

If you need to debug a PHP script but do not have debugging tools at hand in your IDE or similar, an easy way to try to see what's happening and what functions are being called is to use PHP's backtracing tools. It can be useful also to include a backtrace when sending or logging errors that have occured on a production website.

debug_backtrace

The debug_backtrace function returns an array of all the functions and object methods that were called, including the parameters that were passed to them. The most recently called function is at index 0.
The following example code outputs the data from a debug_backtrace using print_r:
function foo($arg1, $arg2, $arg3) {
    bar();
}

function bar() {
    print_r(debug_backtrace());
}

foo('apple', 'banana', 'pear');
The output from the backtrace is:
Array
(
    [0] => Array
        (
            [file] => /common/temp/backtrace-example.php
            [line] => 4
            [function] => bar
            [args] => Array
                (
                )

        )

    [1] => Array
        (
            [file] => /common/temp/backtrace-example.php
            [line] => 12
            [function] => foo
            [args] => Array
                (
                    [0] => apple
                    [1] => banana
                    [2] => pear
                )

        )

)
As you can see each entry in the backtrace contains the file and line that the function was called from, the function that was called and the arguments (or parameters) that were passed to the function.
If you wanted to send a backtrace by email or log it to a file, pass "true" as the second parameter to the print_r function and it will instead return a string which can be emailed or logged to file:
$backtrace = print_r(debug_backtrace(), true);

debug_print_backtrace

The debug_print_backtrace is another backtracing function which prints the backtrace to standard output in a more concise manner. To capture the output to a string you would need to use the output buffering functions.
If debug_print_backtrace() was called in the same place in the example script above in place of debug_backtrace() it would output the following:
#0  bar() called at [/common/temp/backtrace-example.php:4]
#1  foo(apple, banana, pear) called at [/common/temp/backtrace-example.php:12]
This contains similar information to debug_backtrace but more concisely.

PHP Versions

debug_backtrace requires PHP >= 4.3.0
debug_print_backtrace requires PHP >= 5.0.0

Backtracking with PHP Part 2

In the part 2 I'll show you how to capture the information from debug_print_backtrace into a string and an alternative method using the Exception object.

Using debug_print_backtrace with output buffering

My last PHP post looked at output buffering with PHP and how to use the ob* functions to start buffering and how to capture output into a string. Using these functions it is possible to capture the output from the debug_print_backtrace function into a string without it displaying on a webpage.
ob_start();
debug_print_backtrace();
$backtrace = ob_get_clean();

Using the Exception object

A simpler method than using the output buffering functions, and which ensures the existing buffers are not affected, is to use the Exception object's getTraceAsString method instead.
$e = new Exception();
$backtrace = $e->getTraceAsString();
The information returned by the getTraceAsString() method is more or less the same as that for the debug_print_backtrace() function and is easier than having to mess around with ob* functions. Note that it cannot be called statically so calling Exception::getTraceAsString() will result in an error ("Fatal error: Non-static method Exception::getTraceAsString() cannot be called statically"). 

Related posts:

0 comments:

Post a Comment