Poszukuję sposobu na wydrukowanie stosu wywołań w PHP.Drukuj stos wywołań PHP
Punkty premiowe, jeśli funkcja opróżnia bufor we/wy.
Poszukuję sposobu na wydrukowanie stosu wywołań w PHP.Drukuj stos wywołań PHP
Punkty premiowe, jeśli funkcja opróżnia bufor we/wy.
Jeśli chcesz wygenerować ślad, szukasz debug_backtrace
i/lub debug_print_backtrace
.
Pierwszy z nich, na przykład, Ci tablicę jak ten (podają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ędzie opróżnić bufor I/O, ale możesz to zrobić samodzielnie, z flush
i/lub ob_flush
.
(patrz instrukcja stronę pierwszego, aby dowiedzieć się, dlaczego „i/lub” ;-))
to regularnie powoduje, że mój php wyczerpuje się pamięć. Polecam rozwiązanie Tobiasza. – peedee
Zobacz debug_print_backtrace
. Chyba możesz później zadzwonić pod numer flush
, jeśli chcesz.
debug_backtrace()
Możecie zajrzeć do debug_backtrace
, czy może debug_print_backtrace
.
Użyj debug_backtrace
, aby uzyskać śledzenie, jakie funkcje i metody zostały wywołane oraz jakie pliki zostały dołączone, które doprowadziły do punktu, w którym zostało wywołane debug_backtrace
.
var_dump(debug_backtrace());
Czy to, co chcesz?
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}"
Ahhhhh. Dzięki. – shaune
Cholera, to jest o wiele lepsze, dlaczego nie mogą zrobić tego domyślnego wyjścia dla debug_print_backtrace()? Mogłoby dodać parametr boolowski "returnTrace" dla tych, którzy chcą go w zmiennej, a nie echo, i byłoby idealnie! – jurchiks
Nie wiem, ile miesięcy próbowałem wymyślić, jak to zrobić, nigdy nie myślałem, że to zadziała – WojonsTech
Aby zalogować ślad
$e = new Exception;
error_log(var_export($e->getTraceAsString(), true));
Dzięki @Tobiasz
Backtrace zrzuca mnóstwo śmieci, że nie trzeba. Potrzeba jest bardzo długa, trudna do odczytania. Wszystko, czego zwykle chcesz, to "co nazwałeś skąd?" Oto proste rozwiązanie funkcji statycznych. Zazwyczaj umieszczam go w klasie o nazwie "debugowanie", która zawiera wszystkie 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++;
}
}
}
to nazwać tak:
debugUtils::callStack(debug_backtrace());
A produkuje wyjście tak:
==================================================
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)
==================================================
Stwórz element $ lub zmień nazwę elementu $ na $ node, big deal ... – Hejazzman
['file' i 'line' nie zawsze są obecne w węźle $] (http://stackoverflow.com/a/6643478/ 210336) –
Jeśli chcesz ślad stosu, który wygląda bardzo podobnie do tego, jak formatuje php wyjątek śledzenie stosu niż użycie 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;
}
ten powróci ślad stosu sformatowany tak:
#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()
phptrace jest doskonałym narzędziem do drukowania PHP stosu w każdej chwili kiedy chcesz bez instalowania żadnych rozszerzeń.
Istnieją dwie główne funkcje phptrace: po pierwsze, wywołaj stos wywołań PHP, który nie musi niczego instalować, po drugie, śledź przebieg wykonywania poleceń php, który musi zainstalować dostarczone rozszerzenie.
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
Czy istnieje wersja systemu Windows? – johnny
proszę spojrzeć na to Utils klasę, może być pomocne:
Zastosowanie:
<?php
/* first caller */
Who::callme();
/* list the entire list of calls */
Who::followme();
klasy Źródło: https://github.com/augustowebd/utils/blob/master/Who.php
dziwne, że nikt nie pisał w ten sposób:
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
To faktycznie drukuje ślad wstecz bez śmieci - tylko jak została wywołana i gdzie.
Rzeczywiście, naprawdę odpowiada to głównemu głosowanemu rozwiązaniu i krócej. Dzięki – brunetton
rozwiązanie Walltearer jest doskonała, szczególnie jeśli zamknięte w „pre” tagu:
<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>
- określający połączeń na oddzielnych liniach, starannie ponumerowane
możliwy duplikat [Jak mogę uzyskać PHP do tworzenia śladu po błędach?] (http://stackoverflow.com/questions/1159216/how-can-i-get-php-to-produce-a-backtrace-upon-errors) – Gordon
... ale te odpowiedzi są lepsze. – Ben