2009-09-14 51 views
201

我正在尋找一種在PHP中打印調用堆棧的方法。打印PHP調用堆棧

如果函數刷新IO緩衝區,則爲獎勵點。

+2

可能重複[我怎樣才能PHP以產生錯誤回溯?](http://stackoverflow.com/questions/1159216/how-can-i-get-php-to-produce-a-backtrace-upon-errors) – Gordon

+10

...但這些迴應更好。 – Ben

回答

109

如果你想生成一個回溯,你正在尋找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" 
    } 
} 


他們顯然不刷新I/O緩衝區,但你可以自己做,flush和/或ob_flush

(見第一個手冊頁,找出爲什麼「和/或」 ;-))

+5

這經常讓我的php耗盡內存。我推薦Tobiasz的解決方案。 – peedee

3

使用debug_backtrace可以回溯已調用的函數和方法,以及包含哪些文件導致調用debug_backtrace的點。

6
var_dump(debug_backtrace()); 

這是做你想做的?

416

更具可讀性比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}" 
+4

Ahhhhh。謝謝。 – shaune

+28

該死的,這太好了,他們爲什麼不能把它作爲debug_print_backtrace()的默認輸出?可以爲那些想要變量的用戶添加一個布爾參數「returnTrace」,而不是回顯,它會是完美的! – jurchiks

+0

我不知道有多少個月來我一直在想如何做,從來沒有想過它會工作 – WojonsTech

32

要記錄跟蹤

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

感謝@Tobiasz

27

回溯轉儲了一大堆的垃圾,你不需要的。它需要很長時間,難以閱讀。你所有想要的只是「什麼叫什麼來自哪裏?」這是一個簡單的靜態功能解決方案。我通常把它放在一個名爲'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) 
================================================== 
+4

因此,使它$元,或$元重命名爲$節點,大不了... – Hejazzman

+1

['文件'和'線'並不總是在$節點](http://stackoverflow.com/a/6643478/ 210336) –

7

如果你想有一個堆棧跟蹤看起來非常相似,PHP如何格式化例外堆棧跟蹤比使用這個功能我寫道:

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() 
3

phptrace是打印PHP堆棧隨時一個偉大的工具,當你想無需安裝任何擴展。

phptrace有兩大功能:一是打印不需要安裝任何東西的PHP調用堆棧,二是跟蹤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 
+0

是否有Windows版本? – johnny

18

奇怪的是,沒有人發佈這種方式:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); 

這實際上打印沒有垃圾回溯 - 只是調用什麼方法和在哪裏。

+1

的確,真的相當於主投票的解決方案,而且更短。 謝謝 – brunetton

0

Walltearer的解決方案是出色的,特別是如果封閉在一個「前」標籤:

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

- 其中規定了單獨行上調用,整齊編號的