代码之家  ›  专栏  ›  技术社区  ›  Justin

打印PHP调用堆栈

  •  224
  • Justin  · 技术社区  · 15 年前

    我正在寻找一种用PHP打印调用堆栈的方法。

    如果函数刷新IO缓冲区,则可获得额外点数。

    15 回复  |  直到 15 年前
        1
  •  626
  •   pmaruszczyk    8 年前

    可读性比 debug_backtrace() :

    $e = new \Exception;
    var_dump($e->getTraceAsString());
    
    #2 /usr/share/php/PHPUnit/Framework/TestCase.php(626): SeriesHelperTest->setUp()
    #3 /usr/share/php/PHPUnit/Framework/TestResult.php(666): PHPUnit_Framework_TestCase->runBare()
    #4 /usr/share/php/PHPUnit/Framework/TestCase.php(576): PHPUnit_Framework_TestResult->run(Object(SeriesHelperTest))
    #5 /usr/share/php/PHPUnit/Framework/TestSuite.php(757): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
    #6 /usr/share/php/PHPUnit/Framework/TestSuite.php(733): PHPUnit_Framework_TestSuite->runTest(Object(SeriesHelperTest), Object(PHPUnit_Framework_TestResult))
    #7 /usr/share/php/PHPUnit/TextUI/TestRunner.php(305): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false)
    #8 /usr/share/php/PHPUnit/TextUI/Command.php(188): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array)
    #9 /usr/share/php/PHPUnit/TextUI/Command.php(129): PHPUnit_TextUI_Command->run(Array, true)
    #10 /usr/bin/phpunit(53): PHPUnit_TextUI_Command::main()
    #11 {main}"
    
        2
  •  133
  •   Pascal MARTIN    15 年前

    如果要生成回溯跟踪,您需要 debug_backtrace 和/或 debug_print_backtrace .


    例如,第一个将为您提供这样的数组 (引用手册) :

    array(2) {
    [0]=>
    array(4) {
        ["file"] => string(10) "/tmp/a.php"
        ["line"] => int(10)
        ["function"] => string(6) "a_test"
        ["args"]=>
        array(1) {
          [0] => &string(6) "friend"
        }
    }
    [1]=>
    array(4) {
        ["file"] => string(10) "/tmp/b.php"
        ["line"] => int(2)
        ["args"] =>
        array(1) {
          [0] => string(10) "/tmp/a.php"
        }
        ["function"] => string(12) "include_once"
      }
    }
    


    flush 和/或 ob_flush

    (请参阅第一页的手册,了解“和/或”;-)的原因)

        3
  •  44
  •   Sydwell    13 年前

    $e = new Exception;
    error_log(var_export($e->getTraceAsString(), true));
    

        4
  •  42
  •   AbstractVoid    9 年前

    奇怪的是,没有人这样发帖:

    debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
    

    这实际上是在没有垃圾的情况下打印回溯-只需调用什么方法以及在哪里。

        5
  •  37
  •   Hejazzman    12 年前

    Backtrace会倾倒大量你不需要的垃圾。它需要很长时间,很难阅读。你想要的只是“从哪里调用什么?”这里是一个简单的静态函数解决方案。我通常将它放在一个名为“debug”的类中,该类包含我的所有调试实用程序函数。

    class debugUtils {
        public static function callStack($stacktrace) {
            print str_repeat("=", 50) ."\n";
            $i = 1;
            foreach($stacktrace as $node) {
                print "$i. ".basename($node['file']) .":" .$node['function'] ."(" .$node['line'].")\n";
                $i++;
            }
        } 
    }
    

    你这样称呼它:

    debugUtils::callStack(debug_backtrace());
    

    它产生如下输出:

    ==================================================
     1. DatabaseDriver.php::getSequenceTable(169)
     2. ClassMetadataFactory.php::loadMetadataForClass(284)
     3. ClassMetadataFactory.php::loadMetadata(177)
     4. ClassMetadataFactory.php::getMetadataFor(124)
     5. Import.php::getAllMetadata(188)
     6. Command.php::execute(187)
     7. Application.php::run(194)
     8. Application.php::doRun(118)
     9. doctrine.php::run(99)
     10. doctrine::include(4)
    ==================================================
    
        6
  •  9
  •   TroySteven    12 年前

    function debug_backtrace_string() {
        $stack = '';
        $i = 1;
        $trace = debug_backtrace();
        unset($trace[0]); //Remove call to this function from stack trace
        foreach($trace as $node) {
            $stack .= "#$i ".$node['file'] ."(" .$node['line']."): "; 
            if(isset($node['class'])) {
                $stack .= $node['class'] . "->"; 
            }
            $stack .= $node['function'] . "()" . PHP_EOL;
            $i++;
        }
        return $stack;
    } 
    

    这将返回如下格式的堆栈跟踪:

    #1 C:\Inetpub\sitename.com\modules\sponsors\class.php(306): filePathCombine()
    #2 C:\Inetpub\sitename.com\modules\sponsors\class.php(294): Process->_deleteImageFile()
    #3 C:\Inetpub\sitename.com\VPanel\modules\sponsors\class.php(70): Process->_deleteImage()
    #4 C:\Inetpub\sitename.com\modules\sponsors\process.php(24): Process->_delete() 
    
        7
  •  8
  •   brettkelly    15 年前
    var_dump(debug_backtrace());
    

    这是你想要的吗?

        8
  •  6
  •   Martin Geisler    15 年前

    看见 debug_print_backtrace . 我想你可以打电话 flush 如果你愿意的话。

        9
  •  5
  •   renenglish    10 年前

    phptrace 是一个很好的工具,可以随时打印PHP堆栈,而无需安装任何扩展。

    详情如下:

    $ ./phptrace -p 3130 -s             # phptrace -p <PID> -s
    phptrace 0.2.0 release candidate, published by infra webcore team
    process id = 3130
    script_filename = /home/xxx/opt/nginx/webapp/block.php
    [0x7f27b9a99dc8]  sleep /home/xxx/opt/nginx/webapp/block.php:6
    [0x7f27b9a99d08]  say /home/xxx/opt/nginx/webapp/block.php:3
    [0x7f27b9a99c50]  run /home/xxx/opt/nginx/webapp/block.php:10 
    
        10
  •  3
  •   Gumbo    15 年前

    debug_backtrace 获取调用了哪些函数和方法以及包含了哪些文件的回溯,从而得出 调试回溯

        11
  •  2
  •   augustowebd    9 年前

    请查看此utils类,可能会有所帮助:

    用法:

    <?php
    /* first caller */
     Who::callme();
    
    /* list the entire list of calls */
    Who::followme();
    

    源类: https://github.com/augustowebd/utils/blob/master/Who.php

        12
  •  2
  •   Geoff Kendall    7 年前

    如果将pre-Waller的标签放入“Waller”溶液中,尤其是:

    <pre>
    <?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
    </pre>
    

    -它在单独的线路上列出呼叫,整齐地编号

        13
  •  1
  •   pix0r    15 年前

    debug_backtrace()

        14
  •  1
  •   Rob    15 年前
        15
  •  1
  •   dev101    6 年前

    我已经适应了 Don Briggs's answer above 使用内部错误日志记录而不是公开打印,这可能是您在实时服务器上工作时最担心的问题。因为要在相同的文件堆栈中添加完整的文件名(例如,要在相同的文件堆栈中添加更多的文件名)和完整的路径选项,所以也可以添加以下选项:

    class debugUtils {
        public static function callStack($stacktrace) {
            error_log(str_repeat("=", 100));
            $i = 1;
            foreach($stacktrace as $node) {
                // uncomment next line to debug entire node stack
                // error_log(print_r($node, true));
                error_log( $i . '.' . ' file: ' .$node['file'] . ' | ' . 'function: ' . $node['function'] . '(' . ' line: ' . $node['line'] . ')' );
                $i++;
            }
            error_log(str_repeat("=", 100));
        } 
    }
    
    // call debug stack
    debugUtils::callStack(debug_backtrace());