Jawaban:
Jika Anda ingin membuat backtrace, Anda mencari debug_backtrace
dan / atau debug_print_backtrace
.
Misalnya, yang pertama akan memberi Anda array seperti ini (mengutip manual) :
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"
}
}
Mereka tampaknya tidak akan menyiram buffer I / O, tetapi Anda dapat melakukannya sendiri, dengan flush
dan / atau ob_flush
.
(lihat halaman manual yang pertama untuk mengetahui mengapa "dan / atau" ;-))
Lebih mudah dibaca daripada 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}"
debug_backtrace
untuk hanya mengembalikan level pertama di stacktrace - solusi ini bekerja untuk saya. Terima kasih!
print_r
akan menyimpan semua pesan.
Backtrace membuang banyak sampah yang tidak Anda butuhkan. Butuh waktu sangat lama, sulit dibaca. Yang Anda inginkan adalah "apa yang disebut dari mana?" Berikut ini adalah solusi fungsi statis sederhana. Saya biasanya meletakkannya di kelas yang disebut 'debug', yang berisi semua fungsi utilitas debugging saya.
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++;
}
}
}
Anda menyebutnya seperti ini:
debugUtils::callStack(debug_backtrace());
Dan itu menghasilkan output seperti ini:
==================================================
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)
==================================================
Aneh bahwa tidak ada yang diposting dengan cara ini:
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
Ini sebenarnya mencetak backtrace tanpa sampah - hanya metode apa yang disebut dan di mana.
Jika Anda ingin jejak stack yang terlihat sangat mirip dengan bagaimana format php jejak stack pengecualian daripada menggunakan fungsi ini saya tulis:
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;
}
Ini akan mengembalikan jejak jejak yang diformat seperti ini:
#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()
$e = new Exception; echo $e->getTraceAsString();
Lihat debug_print_backtrace
. Saya kira Anda dapat menelepon flush
setelah itu jika Anda mau.
phptrace adalah alat yang hebat untuk mencetak tumpukan PHP kapan saja Anda inginkan tanpa menginstal ekstensi apa pun.
Ada dua fungsi utama dari phptrace: pertama, print call stack PHP yang tidak perlu menginstal apa pun, kedua, lacak arus eksekusi php yang perlu menginstal ekstensi yang disediakannya.
sebagai berikut:
$ ./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
Gunakan debug_backtrace
untuk mendapatkan backtrace dari fungsi dan metode apa yang telah dipanggil dan file apa yang dimasukkan yang mengarah ke titik di mana debug_backtrace
telah dipanggil.
silakan lihat kelas utils ini, semoga bermanfaat:
Pemakaian:
<?php
/* first caller */
Who::callme();
/* list the entire list of calls */
Who::followme();
Kelas sumber: https://github.com/augustowebd/utils/blob/master/Who.php
Anda mungkin ingin melihat ke dalam debug_backtrace
, atau mungkin debug_print_backtrace
.
Solusi Walltearer sangat baik, terutama jika disertakan dalam tag 'pra':
<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>
- yang menetapkan panggilan pada saluran terpisah, bernomor rapi
Saya telah mengadaptasi jawaban Don Briggs di atas untuk menggunakan logging kesalahan internal alih-alih pencetakan publik, yang mungkin menjadi perhatian besar Anda ketika bekerja pada server langsung. Juga, menambahkan beberapa modifikasi seperti opsi untuk memasukkan path file lengkap alih-alih nama dasar (karena, mungkin ada file dengan nama yang sama di jalur yang berbeda), dan juga (bagi mereka yang membutuhkannya) output node stack lengkap:
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());