另一種操作和印出回溯追蹤的方法,無需使用輸出緩衝
<?php
// 印出回溯追蹤,去除每個檔案中重複的絕對路徑
$e = new Exception();
print_r(str_replace('/path/to/code/', '', $e->getTraceAsString()));
?>
(PHP 5, PHP 7, PHP 8)
debug_print_backtrace — 印出回溯追蹤
options
此參數是下列選項的位元遮罩
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]
另一種操作和印出回溯追蹤的方法,無需使用輸出緩衝
<?php
// 印出回溯追蹤,去除每個檔案中重複的絕對路徑
$e = new Exception();
print_r(str_replace('/path/to/code/', '', $e->getTraceAsString()));
?>
我喜歡 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;
}
?>
如果您看到字串參數被截斷,像這樣:
#0 hook.php(324): output_notice('checkout_before...')
#1 hook.php(348): invoke_hook('checkout_before...', Array)
您可以透過 PHP INI 設定來增加印出追蹤資訊中參數的最大長度:
<?php
ini_set('zend.exception_string_param_max_len', 100);
debug_print_backtrace();
?>
…這樣您就可以看到完整的參數了
#0 hook.php(324): output_notice('checkout_before_payment')
#1 hook.php(348): invoke_hook('checkout_before_payment', Array)
在極端情況下,它甚至可能會揭露您以前沒有注意到的巢狀追蹤。
如果您在 HTML 中顯示錯誤訊息(使用適當的實體編碼確保安全),這個函式將無法正常運作,因為它使用換行符號進行格式化。
以下是一個功能類似的函式,但使用 <BR> 標籤。將它插入程式碼的開頭附近,僅將堆疊資訊添加到警告輸出中,或者根據您的喜好修改它
// 以下是在 HTML 中輸出錯誤堆疊的程式碼
function error_handler_callback($errno,$message,$file,$line,$context)
{
if ($errno === E_WARNING)
echo "堆疊,由內而外:<br>".nl2br((new Exception())->getTraceAsString());
return false; // 執行預設的錯誤處理程式
}
set_error_handler("error_handler_callback");