For most compiled languages, such as C, Java, and C#, we can easily perform breakpoint debugging, but PHP must be installed XDebug and complex configuration in the editor can achieve breakpoint debugging capabilities.
However, if it is just simple debugging and viewing the stack traceback, PHP has actually prepared two functions for us, which allows us to very conveniently see the calling status of the program when it is running.
debug_backtrace()
It can be seen from the literal meaning of this method that it means debugging backtrace, and what is returned is an array of backtrace information. .
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/博客文章/dev-blog/php/202004/source/PHP打印跟踪调试信息.php" // 'line' => // int(12) // 'function' => // string(6) "a_test" // 'args' => // array(1) { // [0] => // string(1) "A" // } // } // }
This method must be called in the function, and there will be no content when used outside the function method. Judging from the content, it outputs \_\_FILE__, \_\_LINE__, \_\_FUNCTION__, $argv and other information about this function. In fact, it is related to the function that currently prints this line.
Of course we can also nest a few more layers of functions to see what the printed content is.
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) { // } // } // }
Yes, the output order of the array is the execution order of a stack. b_test() is called first, so it is at the bottom of the stack, and the corresponding output is the last element in the array.
is also used similarly in classes.
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) { // } // } // }
When used in a class, there will be an additional object field in the array item, which displays information about the class where this method is located.
The function declaration of debug_backtrace() is:
debug_backtrace ([ int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT [, int $limit = 0 ]] ) : array
\$options are two constants that can be defined. DEBUG_BACKTRACE_PROVIDE_OBJECT indicates whether to fill the index of "object";
DEBUG_BACKTRACE_IGNORE_ARGS Whether to ignore the index of "args", including all function/method parameters, can save memory overhead. $limits can be used to limit the number of stack frames returned. The default is 0 to return all stacks.
debug_backtrace() and the debug_print_backtrace() method to be introduced below support the code in require/include files and eval(). When embedding a file, the path to the embedded file will be output. You can do this yourself try.
debug_print_backtrace()
This method can also be seen from the name. It will directly print the backtrace content. Its function declaration is the same as debug_backtrace(), but $options defaults to DEBUG_BACKTRACE_IGNORE_ARGS, which means it only prints the file and line number where the call is made.
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]
In addition, this function does not need to use var_dump() or print_r() for output. If you use this function directly, it will output. It allows us to debug very quickly and conveniently.
For example, in large frameworks such as laravel, when the controller needs to view stack information, we can use debug_print_backtrace() to quickly view the current stack call situation. If debug_backtrace() does not specify $options, it will occupy a very large memory capacity or cannot be displayed completely.
Summary
The two functions introduced today can flexibly help us debug the code or understand the calling situation of a framework. Of course, under formal circumstances, it is recommended to use Xdebug plus editor support for breakpoint debugging, because we cannot see changes in variables using the debug_backtrace() methods.
Test code:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/PHP%E6%89%93%E5%8D%B0%E8%B7%9F%E8%B8%AA%E8%B0%83%E8%AF%95%E4%BF%A1%E6%81%AF.php
Recommended learning: php video tutorial