Respuestas:
Si desea generar una traza inversa, está buscando debug_backtrace
y / o debug_print_backtrace
.
El primero, por ejemplo, te dará una matriz como esta (citando el manual) :
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"
}
}
Aparentemente no vaciarán el búfer de E / S, pero puede hacerlo usted mismo, con flush
y / o ob_flush
.
(Consulte la página del manual de la primera para averiguar por qué "y / o" ;-)
Más legible 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
para devolver solo el primer nivel en el stacktrace: esta solución hace el trabajo por mí. ¡Gracias!
print_r
retendrá todos los mensajes.
Backtrace arroja una gran cantidad de basura que no necesita. Se tarda mucho, es difícil de leer. Todo lo que siempre quieres es "¿cómo se llama qué de dónde?" Aquí hay una solución simple de función estática. Normalmente lo pongo en una clase llamada 'depuración', que contiene todas mis funciones de utilidad de depuración.
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++;
}
}
}
Lo llamas así:
debugUtils::callStack(debug_backtrace());
Y produce resultados como este:
==================================================
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)
==================================================
Es extraño que nadie haya publicado de esta manera:
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
Esto realmente imprime la traza inversa sin la basura, solo qué método se llamó y dónde.
Si desea un seguimiento de la pila que se parece mucho a cómo php formatea el seguimiento de la pila de excepción que usar esta función, escribí:
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;
}
Esto devolverá una traza de pila formateada así:
#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();
Ver debug_print_backtrace
. Supongo que puedes llamar flush
después si quieres.
phptrace es una gran herramienta para imprimir la pila PHP en cualquier momento cuando lo desee sin instalar ninguna extensión.
Hay dos funciones principales de phptrace: primero, imprimir la pila de llamadas de PHP que no necesita instalar nada, segundo, rastrear los flujos de ejecución de php que necesitan instalar la extensión que proporciona.
como sigue:
$ ./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
Se utiliza debug_backtrace
para obtener un seguimiento de las funciones y métodos que se han llamado y qué archivos se han incluido que condujeron al punto donde debug_backtrace
se ha llamado.
Eche un vistazo a esta clase de utilidades, puede ser útil:
Uso:
<?php
/* first caller */
Who::callme();
/* list the entire list of calls */
Who::followme();
Clase de origen: https://github.com/augustowebd/utils/blob/master/Who.php
Es posible que desee investigar debug_backtrace
, o tal vez debug_print_backtrace
.
La solución de Walltearer es excelente, particularmente si está encerrada en una etiqueta 'pre':
<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>
- que establece las llamadas en líneas separadas, perfectamente numeradas
He adaptado la respuesta de Don Briggs anterior para usar el registro de errores internos en lugar de la impresión pública, lo que puede ser su gran preocupación cuando trabaje en un servidor en vivo. Además, se agregaron algunas modificaciones más, como la opción de incluir la ruta completa del archivo en lugar del nombre básico (porque podría haber archivos con el mismo nombre en diferentes rutas) y también (para aquellos que lo requieran) una salida completa de la pila de nodos:
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());