debug_print_backtrace

(PHP 5, PHP 7, PHP 8)

debug_print_backtrace 打印回溯

描述

debug_print_backtrace(int $options = 0, int $limit = 0): void

debug_print_backtrace() 打印 PHP 回溯。它打印函数调用、included/required 文件和 eval()ed 内容。

参数

options

此参数是以下选项的位掩码

debug_print_backtrace() 选项
DEBUG_BACKTRACE_IGNORE_ARGS 是否省略 "args" 索引,以及所有函数/方法参数,以节省内存。

limit

此参数可用于限制打印的堆栈帧数量。默认情况下 (limit=0) 它打印所有堆栈帧。

返回值

不返回值。

示例

示例 #1 debug_print_backtrace() 示例

<?php
// include.php 文件

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]

参见

添加备注

用户贡献的备注 5 则备注

87
bishop
15 年前
另一种操纵和打印回溯的方法,不使用输出缓冲

<?php
// 打印回溯,去除每个文件重复的绝对路径
$e = new Exception();
print_r(str_replace('/path/to/code/', '', $e->getTraceAsString()));
?>
25
dany dot dylan at gmail dot com
15 年前
我喜欢 debug_print_backtrace() 的输出,但我有时希望它作为字符串。

bortuzar 使用输出缓冲的解决方案很棒,但我希望将其分解成一个函数。但是,这样做总是导致我在堆栈顶部使用任何函数名称,这是多余的。

以下是我的简单解决方案。如果您不关心重新编号调用堆栈,请省略第二个 preg_replace()。

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

// 从回溯中删除第一个项目,因为它就是这个函数,是多余的。
// 这是多余的。
$trace = preg_replace ('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);

// 重新编号回溯项目。
$trace = preg_replace ('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);

return
$trace;
}
?>
-2
David Spector
4 年前
如果您在 HTML 中显示错误消息(使用实体进行适当的安全保障),此函数将无法正常工作,因为它使用换行符进行格式化。

以下是一个类似的函数,但使用 <BR> 标签。将其插入程序开头,仅将堆栈添加到警告输出中,或根据需要对其进行修改

// 以下是用于在 HTML 中输出错误堆栈的代码
function error_handler_callback($errno,$message,$file,$line,$context)
{
if ($errno === E_WARNING)
echo "Stack, innermost first:<br>".nl2br((new Exception())->getTraceAsString());
return false; // 执行常规错误处理程序
}
set_error_handler("error_handler_callback");
-12
AB
8 年前
此代码将为您提供一个简单的水平堆栈跟踪,以帮助调试

<?php

class A {
public function
testA() {
echo
"<LI>类 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>类 B.testB";
echo
"<LI>".$this->whoDidThat();
}
public function
testA() {
echo
"<LI>类 testB.testA ---- Y";
echo
"<LI>".$this->whoDidThat();
}
}
class
C {
public function
test() {
echo
"<HR>";
$b=new B();
echo
"<HR>类 C 调用 B.testA";
$b->testA();
}
}

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

运行后,您将看到

类 C 调用 B.testA
*类 testB.testA ---- Y
*[line45]C.test>[line40]B.testA
-11
chris dot kistner at gmail dot com
14 年前
这是一个函数,它返回一个字符串,其中包含与 debug_print_backtrace() 中显示的相同信息,并且可以选择排除一定数量的跟踪(通过更改 $traces_to_ignore 参数)。

我已经进行了一些测试以确保它打印出完全相同的信息,但我可能错过了一些东西。

这个解决方案是一种很好的变通方法,如果您的 PHP 代码中已经使用了 ob_start(),则可以获取 debug_print_backtrace() 信息。

<?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 = ''; // 找到私有变量
}
$args[] = '['.$key.'] => '.get_arg($value);
}

$arg = get_class($arg) . ' Object ('.implode(',', $args).')';
}
}
?>
To Top