PHP 7.2.0 Release Candidate 2 Released

debug_print_backtrace

(PHP 5, PHP 7)

debug_print_backtrace 打印一条回溯。

说明

void debug_print_backtrace ([ int $options = 0 [, int $limit = 0 ]] )

debug_print_backtrace() 打印了一条 PHP 回溯。它打印了函数调用、被 included/required 的文件和 eval() 的代码。

参数

options

从 5.3.6 开始,这个参数是以下选项的位掩码:

debug_print_backtrace() 选项
DEBUG_BACKTRACE_IGNORE_ARGS 是否忽略 "args" 的索引,包括所有的 function/method 的参数,能够节省内存开销。

limit

从 5.4.0 开始,这个参数能够用于限制返回堆栈帧的数量。 默认为 (limit=0) ,返回所有的堆栈帧。

返回值

没有返回值。

更新日志

版本 说明
5.4.0 添加了可选的参数 limit
5.3.6 添加了可选的参数 options

范例

Example #1 debug_print_backtrace() 范例

<?php
// include.php file

function a() {
    
b();
}

function 
b() {
    
c();
}

function 
c(){
    
debug_print_backtrace();
}

a();

?>
<?php
// 文件 test.php
// 这是你应该运行的文件

include 'include.php';
?>

以上例程的输出类似于:

#0  c() called at [/tmp/include.php:10]
#1  b() called at [/tmp/include.php:6]
#2  a() called at [/tmp/include.php:17]
#3  include(/tmp/include.php) called at [/tmp/test.php:3]

参见

add a note add a note

User Contributed Notes 7 notes

up
36
bishop
8 years ago
Another way to manipulate and print a backtrace, without using output buffering:

<?php
// print backtrace, getting rid of repeated absolute path on each file
$e = new Exception();
print_r(str_replace('/path/to/code/', '', $e->getTraceAsString()));
?>
up
13
dany dot dylan at gmail dot com
8 years ago
I like the output of debug_print_backtrace() but I sometimes want it as a string.

bortuzar's solution to use output buffering is great, but I'd like to factorize that into a function.  Doing that however always results in whatever function name I use appearing at the top of the stack which is redundant.

Below is my noddy (simple) solution.  If you don't care for renumbering the call stack, omit the second preg_replace().

<?php
   
function debug_string_backtrace() {
       
ob_start();
       
debug_print_backtrace();
       
$trace = ob_get_contents();
       
ob_end_clean();

       
// Remove first item from backtrace as it's this function which
        // is redundant.
       
$trace = preg_replace ('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);

       
// Renumber backtrace items.
       
$trace = preg_replace ('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);

        return
$trace;
    }
?>
up
0
aidan at php dot net
12 years ago
This functionality is now implemented in the PEAR package PHP_Compat.

More information about using this function without upgrading your version of PHP can be found on the below link:

http://pear.php.net/package/PHP_Compat
up
-2
AB
1 year ago
This code will give you a simple horizontal stack trace to assist debugging:

<?php

class A {
    public function
testA() {
        echo
"<LI>Class A.testA ----??";
        echo
"<LI>".$this->whoDidThat();
    }
    public function
whoDidThat() {
       
$who=debug_backtrace();
       
$result="";
       
$count = 0;
       
$last=count($who);
        foreach(
$who as $k=>$v) {
            if (
$count++ > 0) {
               
$x="";
                if (
$count>2) {
                   
$x=">";
                }
               
$result="[line".$who[$k]['line']."]".$who[$k]['class'].".".$who[$k]['function'].$x.$result;
            }
        }
        return
$result;
    }
}
class
B extends A {
    public function
testB() {
        echo
"<LI>Class B.testB";
        echo
"<LI>".$this->whoDidThat();
    }
    public function
testA() {
        echo
"<LI>Class testB.testA  ---- Y";
        echo
"<LI>".$this->whoDidThat();
    }
}
class
C {
    public function
test() {
        echo
"<HR>";
       
$b=new B();
        echo
"<HR>Class C calling B.testA";
       
$b->testA();
    }
}

$c=new C();
$c->test();
echo
debug_print_backtrace();
?>

When run you get

Class C calling B.testA
*Class testB.testA ---- Y
*[line45]C.test>[line40]B.testA
up
-9
bortuzar at gmail dot com
10 years ago
If you want to get the trace into a variable or DB, I suggest to do the following:

<?php
    ob_start
();
       
debug_print_backtrace();
   
$trace = ob_get_contents();
   
ob_end_clean();

$query = sprintf("INSERT INTO EventLog (Trace) VALUES ('%s')",
           
mysql_real_escape_string($trace));
mysql_query($query);
?>
up
-7
chris dot kistner at gmail dot com
7 years ago
Here's a function that returns a string with the same information shown in debug_print_backtrace(), with the option to exclude a certain amount of traces (by altering the $traces_to_ignore argument).

I've done a couple of tests to ensure that it prints exactly the same information, but I might have missed something.

This solution is a nice workaround to get the debug_print_backtrace() information if you're already using ob_start() in your PHP code.

<?php
function get_debug_print_backtrace($traces_to_ignore = 1){
   
$traces = debug_backtrace();
   
$ret = array();
    foreach(
$traces as $i => $call){
        if (
$i < $traces_to_ignore ) {
            continue;
        }

       
$object = '';
        if (isset(
$call['class'])) {
           
$object = $call['class'].$call['type'];
            if (
is_array($call['args'])) {
                foreach (
$call['args'] as &$arg) {
                   
get_arg($arg);
                }
            }
        }       

       
$ret[] = '#'.str_pad($i - $traces_to_ignore, 3, ' ')
        .
$object.$call['function'].'('.implode(', ', $call['args'])
        .
') called at ['.$call['file'].':'.$call['line'].']';
    }

    return
implode("\n",$ret);
}

function
get_arg(&$arg) {
    if (
is_object($arg)) {
       
$arr = (array)$arg;
       
$args = array();
        foreach(
$arr as $key => $value) {
            if (
strpos($key, chr(0)) !== false) {
               
$key = '';    // Private variable found
           
}
           
$args[] =  '="keyword">)) !== false        echo
"<HR>"up) {
   yword">=>
[d"> class="default">$who)" class="usernotes-voteu">up
""            if ();
?>
$arr (""  a>
;
        echo
(&l>$arr (&l>$arr (&p;     debs="usernotes-voteu">up(&p; &nbpan>$call[is_object}(an> s:eass="default">false ss="default">$ret[] = [
When run you get

Clasfword">++ >
$query /strspan class="default">$qunseyword">;
    &nban clalass="degu/><?php
$query /strspan class="default">$qunseyword">;
    &nban clalass="degu/kss="keywo0n &nbs /strspan class="default"si /stry0ire7class="t &n0>$query
/strspan claEpan "keyword">)) !==
) {
      &nbsass=class="keyword">->
whoDidThat();
bsp;     &nbsass=class="keyword">->
$yword">(();
Lsp; &x   echo
(&l>$a]keyword">[xnenbsp;       .$o">$query /strspan class="default">$qunseyword">;
    &nban clalass="degu/kss="ke sL7 years ago();.$call()ban clalass="degu/kss="ke sL7 years ago.
ob_end_clean();

$querer;
; $querer;
; &stsr>; sr>; $querer;  ss="default class="s="keyword"n c_42&page=function.debug-print-backtrace&vote=down" title="Vote down!" class="usernote>']l1s 5.4.0 开始,这nepan>       s']lsamp;efault">$yword">(= get_argget_argsyan class="kepan c5ss="ke sL7 years ago.$result=$trace $call()ban r>7 years ago$query /st/spanin amountspanIoumted">down
2c;     7 years ago(rword"> 2faul1 $trace mysql_rclass="defauolt">$qsL7 years ago(rword"> 2faul1 imysqn>
= <)span>
$querer;  a>
v
N\pan>();
bsp; 5N)econtinue;
    &nbskeyword">();
bsp;     &nbsass=clbsp; &-m>(rword"> 2faul5ault">mysql_rclass="defauolt">$qsL7 years ago(rword"> 2faul1 i(rword"> 2faul1]v> 'n classtsr>;:an class="string">']sd">();

lspan class="keyword">();
print_r(= (&l>$arr nbsp; &nhld86932"> = = = .$result= 7 years ago= yword"4class="keyword">();
bsp; 5N)econtinue;
    &nbskeyword">();
bsp;   efault">$arr
= yword"4class="keyworrace();
&nbs
$trace ();
bsp; 5N)ed cl m eci eOr at gmail dot com
] as &    foreac/div>
2c;    /vote-note.php?id=97101&page=function.debugersion of PHP can be found on the below li_(classrivate variablmation if you're already using ob_start() in your PHP code.

);
();
bsp; 5N)ed cl m eci eOr at gmail dot com$call);
function
get_debug_prinpan class="default">0)) !== false();
bsp; 5N)ed cl m eci eOr at gmail dot com
7 ye ();
bsp; 5N)ed cl m eci eOr at gmai;h0n$traces ();
?>
an>debs="usernotes-voteu">up "usernotes-voteu">up r\4ord">;
    &nban clalass="d"> 2faul1 i(rword"> 2faul1]v> 'n clard">[] =
'#' "usernotes-voteu">up "userno; &nbstring">'args' 2faul1 i(rwo">= s dot kistner at gmail dot com() {< 7ae ai)lass="string">':'();// Private variable found
  &nt">// Private variable found;
    &nbsS 7ae ai)lass="string">':'
();amp;();// Private variables>?>'keyword">;
    &nass(ss="st>// Private variable founds r />)" class="usernoteslass="doe ap;'n cla="s uale ap;   lass="stsr>;:an cfault" class="usernoteslass="doe ap;'n cla="s uale ap;   lass="stsr>;:an cfault" c] />        .') called atpan>falsen> nbVn0 'keyword">;
    &nass(ss="st>
More information abPd"> gmai;h0n$="string">'keyword">;Inu0c