1. 程式人生 > 程式設計 >PHP如何列印跟蹤除錯資訊

PHP如何列印跟蹤除錯資訊

對於大部分編譯型語言來說,比如 C 、 java 、 C# ,我們都能很方便地進行斷點除錯,但是 php 則必須安裝 XDebug 並且在編輯器中進行復雜的配置才能實現斷點除錯的能力。不過,如果只是簡單的除錯並且檢視堆疊回溯的話,其實 PHP 已經為我們準備好了兩個函式,能夠讓我們非常方便的看到程式執行時的呼叫情況。

debug_backtrace()

從這個方法的字面意思上就可以看出,它的意思就是除錯回溯,返回的也正是一段回溯資訊的陣列。

function a_test($str)
{
    echo "Hi: $str",PHP_EOL;
    var_dump(debug_backtrace());
}

var_dump(debug_backtrace());

a_test("A");

// Hi: A/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php:7:
// array(1) {
//   [0] =>
//   array(4) {
//     'file' =>
//     string(93) "/Users/zhangyue/MyDoc/部落格文UcRiPoerge
章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php" // 'line' =&g程式設計客棧t; // int(12) // 'function' => // string(6) "a_test" // 'args' => // array(1) { // [0] => // string(1) "A" // } // } // }

這個方法必須在函式中呼叫,在函式程式設計客棧方法外部使用是不會有內容的。從內容中看,它輸出了關於這個函式的 __FILE__ 、 __LINE__ 、 __FUNCTION__ 、$argv 等資訊。其實就是關於當前列印這行所在函式的相關內容。

我們當然也可以多巢狀幾層函式來看一下打印出的內容是什麼。

function b程式設計客棧_test(){
    c_test();
}

function c_test(){
    a_test("b -> c -> a");
}

b_test();

// Hi: b -> c -> a
// /Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php:7:
// array(3) {
//   [0] =>
//   array(4) {
//     'file' =>
//     string(93) "/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php"
//     'line' =>
//     int(37)
//     'function' =>
//     string(6) "a_test"
//     'args' =>
//     array(1) {
//       [0] =>
//       string(11) "b -> c -> a"
//     }
//   }
//   [1] =>
//   array(4) {
//     'file' =>
//     string(93) "/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php"
//     'line' =>
//     int(33)
//     'function' =>
//     string(6) "c_test"
//     'args' =>
//     array(0) {
//     }
//   }
//   [2] =>
//   array(4) {
//     'file' =>
//     string(93) "/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php"
//     'line' =>
//     int(40)
//     'function' =>
//     string(6) "b_test"
//     'args' =>
//     array(0) {
//     }
//   }
// }

沒錯,陣列的輸出順序就是一個棧的執行順序,b_test() 最先呼叫,所以它在棧底,對應的輸出也就是陣列中的最後一個元素。

在類中也是類似的使用方法。

class A{
    function test_a(){
        $this->test_b();
    }
    function test_b(){
        var_dump(debug_backtrace());
    }
}

$a = new A();
$a->test_a();

// /Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php:90:
// array(2) {
//   [0] =>
//   array(7) {
//     'file' =>
//     string(93) "/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php"
//     'line' =>
//     int(87)
//     'function' =>
//     string(6) "test_b"
//     'class' =>
//     string(1) "A"
//     'object' =>
//     class A#1 (0) {
//     }
//     'type' =>
//     string(2) "->"
//     'args' =>
//     array(0) {
//     }
//   }
//   [1] =>
//   array(7) {
//     'file' =>
//     string(93) "/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php"
//     'line' =>
//     int(95)
//     'function' =>
//     string(6) "test_a"
//     'class' =>
//     string(1) "A"
//     'object' =>
//     class A#1 (0) {
//     }
//     'type' =>
//     string(2) "->"
//     'args' =>
//     array(0) {
//     }
//   }
// }

在類中使用的時候,在陣列項中會多出一個 object 欄位,顯示的是這個方法所在類的資訊。

debug_backtrace() 的函式宣告是:

debug_backtrace ([ int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT [,int $limit = 0 ]] ) : array

其中 options 是有兩個常量可以定義,DEBUG_BACKTRACE_PROVIDE_OBJECT 表明是否填充 "object" 的索引;DEBUG_BACKTRACE_IGNORE_ARGS 是否忽略 "args" 的索引,包括所有的 function/method 的引數,能夠節省記憶體開銷。limits 可用於限制返回堆疊幀的數量,預設為0返回所有的堆疊。

debug_backtrace() 以及下面要介紹的 debug_print_backtrace() 方法都是支援 require/include 檔案以及 eval() 中的程式碼的,在嵌入檔案時,會輸出嵌入檔案的路徑,這個大家可以自行嘗試。

debug_print_backtrace()

這個方法從名稱也可以看出,它會直接列印回溯內容,它的函式宣告和 debug_backtrace() 是一樣的,不過 $options 預設是 DEBUG_BACKTRACE_IGNORE_ARGS ,也就是說,它只打印呼叫所在檔案及行數。

function a() {
    b();
}

function b() {
    c();
}

function c(){
    debug_print_backtrace();
程式設計客棧}

a();

#0  c() called at [/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php:144]
#1  b() called at [/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php:140]
#2  a() called at [/Users/zhangyue/MyDoc/部落格文章/dev-blog/php/202004/source/PHP列印跟蹤除錯資訊.php:151]

另外就是這個函式不需要使用 var_dump() 或 print_r() 進行輸出,直接使用這個函式就會進行輸出。能夠非常快捷方便的讓我們進行除錯,比如在 laravel 這類大型框架中,我們在控制器需要檢視堆疊資訊時,就可以使用 debug_print_backtrace() 快速地檢視當前的堆疊呼叫情況。而 debug_backtrace() 如果沒有指定 $options 的話,則會佔用非常大的記憶體容量或者無法完整顯示。

總結

今天介紹的這兩個函式能夠靈活地幫助我們除錯程式碼或者瞭解一個框架的呼叫情況。當然,在正式的情況下還是推薦使用 Xdebug 加上編輯器的支援來進行斷點除錯,因為使用 debug_backtrace() 這兩個方法我們無法看到變數的變化情況。

測試程式碼:

github.com/zhangyue050…

以上就是PHP如何列印跟蹤除錯資訊的詳細內容,更多關於PHP列印除錯資訊的資料請關注我們其它相關文章!