Ответы:
Если вы хотите создать обратную трассировку, вы ищете 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
.
(см. страницу руководства первой, чтобы узнать, почему "и / или" ;-))
Более читабельно, чем 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
чтобы вернуть только первый уровень в трассировке стека - это решение работает для меня. Спасибо!
print_r
сохранит все сообщения.
Backtrace сбрасывает много мусора, который вам не нужен. Это занимает очень много времени, трудно читать. Все, что вы обычно когда-либо хотите, это "что называется, откуда?" Вот простое решение статической функции. Я обычно помещаю его в класс под названием «отладка», который содержит все мои вспомогательные функции отладки.
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)
==================================================
Странно, что никто так не писал
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
Это на самом деле печатает обратную трассировку без мусора - только то, что метод был вызван и где.
Если вам нужна трассировка стека, которая очень похожа на то, как 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()
$e = new Exception; echo $e->getTraceAsString();
См debug_print_backtrace
. Я думаю, вы можете позвонить flush
потом, если хотите.
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
Используйте, debug_backtrace
чтобы получить обратную информацию о том, какие функции и методы были вызваны и какие файлы были включены, что привело к точке, где debug_backtrace
был вызван.
пожалуйста, посмотрите на этот класс утилит, может быть полезно:
Использование:
<?php
/* first caller */
Who::callme();
/* list the entire list of calls */
Who::followme();
Исходный класс: https://github.com/augustowebd/utils/blob/master/Who.php
Возможно, вы захотите посмотреть debug_backtrace
, или, может быть debug_print_backtrace
.
Решение Walltearer превосходно, особенно если оно заключено в тег «pre»:
<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>
- который излагает звонки на отдельных линиях, аккуратно пронумерованных
Я адаптировал ответ Дона Бриггса выше, чтобы использовать внутреннюю регистрацию ошибок вместо общедоступной печати, которая может быть вашей большой проблемой при работе на живом сервере. Кроме того, добавлено еще несколько модификаций, таких как опция, включающая полный путь к файлу вместо базового имени (потому что могут быть файлы с одинаковыми именами в разных путях), а также (для тех, кому это требуется) вывод полного стека узлов:
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());