Відповіді:
Якщо ви хочете створити зворотний трек, ви шукаєте 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
збереже всі повідомлення.
Назад викидає багато сміття, яке вам не потрібно. Це займає дуже довго, важко читати. Все, що ви завжди хочете - це "що називати, що звідки?" Ось просте рішення з статичною функцією. Зазвичай я кладу його у клас під назвою "налагодження", який містить усі мої функції налагодження.
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>
<?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());