Odpowiedzi:
Jeśli chcesz wygenerować ślad, szukasz debug_backtrace
i / lub debug_print_backtrace
.
Pierwszy, na przykład, da ci tablicę taką jak ta (cytując instrukcję) :
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"
}
}
Najwyraźniej nie będą opróżniać bufora we / wy, ale możesz to zrobić samodzielnie, za pomocą flush
i / lub ob_flush
.
(zobacz stronę podręcznika pierwszego, aby dowiedzieć się, dlaczego „i / lub” ;-))
Bardziej czytelny niż 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
aby zwrócić tylko pierwszy poziom w stacktrace - to rozwiązanie działa dla mnie. Dziękuję Ci!
print_r
zachowa wszystkie wiadomości.
Backtrace zrzuca całe śmieci, których nie potrzebujesz. Trwa bardzo długo, trudny do odczytania. Wszystko, czego zwykle pragniesz, to „jak się nazywa, skąd?” Oto proste rozwiązanie funkcji statycznej. Zwykle umieszczam go w klasie o nazwie „debugowanie”, która zawiera wszystkie moje funkcje narzędzia do debugowania.
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++;
}
}
}
Nazywasz to tak:
debugUtils::callStack(debug_backtrace());
I produkuje takie dane wyjściowe:
==================================================
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)
==================================================
Dziwne, że nikt nie opublikował w ten sposób:
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
To faktycznie drukuje ślad bez śmieci - tylko jaka metoda została wywołana i gdzie.
Jeśli chcesz śledzenia stosu, który wygląda bardzo podobnie do tego, jak php formatuje wyjątek śledzenia stosu, niż użyj tej funkcji, napisałem:
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;
}
Zwróci to ślad stosu sformatowany w następujący sposób:
#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();
Zobaczyć debug_print_backtrace
. Chyba możesz flush
później zadzwonić, jeśli chcesz.
phptrace to świetne narzędzie do drukowania stosu PHP w dowolnym momencie, bez potrzeby instalowania żadnych rozszerzeń.
Istnieją dwie główne funkcje phptrace: po pierwsze, stos wywołań drukowania PHP, które nie muszą niczego instalować, po drugie, śledzenie przepływów wykonania php, które wymaga zainstalowania rozszerzenia, które dostarcza.
następująco:
$ ./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
Służy debug_backtrace
do uzyskania informacji o tym, jakie funkcje i metody zostały wywołane oraz jakie pliki zostały zawarte, które doprowadziły do momentu, w którym debug_backtrace
zostały wywołane.
spójrz na tę klasę utils, może być pomocna:
Stosowanie:
<?php
/* first caller */
Who::callme();
/* list the entire list of calls */
Who::followme();
Klasa źródłowa: https://github.com/augustowebd/utils/blob/master/Who.php
Możesz zajrzeć debug_backtrace
, a może debug_print_backtrace
.
Rozwiązanie Walltearer jest doskonałe, szczególnie jeśli jest umieszczone w tagu „pre”:
<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>
- który określa połączenia na osobnych liniach, starannie ponumerowanych
Zaadaptowałem powyższą odpowiedź Dona Briggsa, aby używać wewnętrznego rejestrowania błędów zamiast drukowania publicznego, co może stanowić poważny problem podczas pracy na serwerze na żywo. Ponadto dodano kilka dodatkowych modyfikacji, takich jak opcja włączenia pełnej ścieżki pliku zamiast podstawowej nazwy (ponieważ mogą istnieć pliki o tej samej nazwie w różnych ścieżkach), a także (dla tych, którzy tego wymagają) kompletny plik wyjściowy stosu węzłów:
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());