Réponses:
Si vous souhaitez générer une trace, vous recherchez debug_backtrace
et / ou debug_print_backtrace
.
Le premier vous donnera, par exemple, un tableau comme celui-ci (en citant le manuel) :
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"
}
}
Apparemment, ils ne videront pas le tampon d'E / S, mais vous pouvez le faire vous-même, avec flush
et / ou ob_flush
.
(voir la page de manuel du premier pour savoir pourquoi le "et / ou" ;-))
Plus lisible que 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
pour ne renvoyer que le premier niveau dans le stacktrace - cette solution fait le travail pour moi. Je vous remercie!
print_r
conservera tous les messages.
Backtrace vide un tas de déchets dont vous n'avez pas besoin. Cela prend très longtemps, difficile à lire. Tout ce que vous voulez habituellement, c'est "ce qui a appelé quoi d'où?" Voici une solution de fonction statique simple. Je le mets généralement dans une classe appelée «débogage», qui contient toutes mes fonctions utilitaires de débogage.
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++;
}
}
}
Vous l'appelez comme ceci:
debugUtils::callStack(debug_backtrace());
Et il produit une sortie comme celle-ci:
==================================================
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)
==================================================
Étrange que personne n'ait publié de cette façon:
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
Cela imprime en fait la trace sans les ordures - juste quelle méthode a été appelée et où.
Si vous voulez une trace de pile qui ressemble beaucoup à la façon dont php formate la trace de pile d'exception, utilisez cette fonction, j'ai écrit:
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;
}
Cela retournera une trace de pile formatée comme ceci:
#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();
Tu vois debug_print_backtrace
. Je suppose que vous pouvez appeler flush
après si vous le souhaitez.
phptrace est un excellent outil pour imprimer la pile PHP à tout moment quand vous le souhaitez sans installer d'extensions.
Il y a deux fonctions principales de phptrace: premièrement, imprimer la pile d'appels de PHP qui n'a pas besoin d'installer quoi que ce soit, deuxièmement, tracer les flux d'exécution de php qui doivent installer l'extension qu'il fournit.
comme suit:
$ ./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
Utilisez debug_backtrace
pour obtenir une trace des fonctions et méthodes qui ont été appelées et des fichiers qui ont été inclus et qui ont conduit au point où ils debug_backtrace
ont été appelés.
s'il vous plaît jeter un oeil à cette classe d'utils, peut être utile:
Usage:
<?php
/* first caller */
Who::callme();
/* list the entire list of calls */
Who::followme();
Classe source: https://github.com/augustowebd/utils/blob/master/Who.php
Vous voudrez peut-être examiner debug_backtrace
, ou peut-être debug_print_backtrace
.
La solution de Walltearer est excellente, en particulier si elle est enfermée dans une étiquette «pré»:
<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>
- qui établit les appels sur des lignes distinctes, soigneusement numérotées
J'ai adapté la réponse de Don Briggs ci-dessus pour utiliser la journalisation des erreurs internes au lieu de l'impression publique, ce qui peut être votre grande préoccupation lorsque vous travaillez sur un serveur en direct. En outre, quelques modifications supplémentaires comme l'option pour inclure le chemin de fichier complet au lieu du nom de base (car il pourrait y avoir des fichiers avec le même nom dans des chemins différents) et également (pour ceux qui en ont besoin) une sortie de pile de nœuds complète:
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());