Pergunta

Eu estou procurando uma maneira de imprimir a pilha de chamadas em PHP.

Os pontos de bónus se a função libera o buffer IO.

Foi útil?

Solução

Se você deseja gerar um backtrace, está à procura de debug_backtrace e / ou debug_print_backtrace .


O primeiro vai, por exemplo, obter uma matriz como este (citando o 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"
  }
}


Eles aparentemente não irá liberar o I / O buffer, mas você pode fazer isso sozinho, com flush e / ou ob_flush .

(veja a página do manual do primeiro para descobrir por que o "e / ou" ;-))

Outras dicas

Mais legível do 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}"

Para o log de rastreamento

$e = new Exception;
error_log(var_export($e->getTraceAsString(), true));

Graças @Tobiasz

Backtrace despeja um monte de lixo que você não precisa. Demora é muito longo, difícil de ler. Tudo que você usuall sempre desejo é "o que chamou que de onde?" Aqui está uma solução função estática simples. Normalmente, eu colocá-lo em uma classe chamada 'debug', que contém todas as minhas funções de utilidade de depuração.

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++;
        }
    } 
}

Você chamá-lo assim:

debugUtils::callStack(debug_backtrace());

E produz uma saída como esta:

==================================================
 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)
==================================================

Estranho que ninguém postou desta maneira:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

Isso realmente imprime backtrace sem o lixo -. Exatamente o método foi chamado e onde

Se você quiser um rastreamento de pilha que parece muito semelhante à forma como php formata o rastreamento da pilha excepção do que o uso dessa função que eu escrevi:

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;
} 

Isso irá retornar um rastreamento de pilha formatado como este:

#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() 
var_dump(debug_backtrace());

O que fazer o que quiser?

debug_print_backtrace . Eu acho que você pode chamar flush depois, se quiser.

phptrace é uma grande ferramenta para imprimir PHP pilha a qualquer momento quando você quer sem instalar qualquer extensão.

Existem duas principais funções da phptrace: a primeira, chamada de impressão pilha de PHP que não precisa instalar nada, segundo, os fluxos de execução traço PHP que precisa para instalar a extensão que fornece

.

como segue:

$ ./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 

Use debug_backtrace para obter um registo de chamadas do que funções e métodos tinha sido chamado e quais arquivos tinha sido incluído o que levou ao ponto onde debug_backtrace foi chamado.

por favor dê uma olhada nesta classe utils, podem ser úteis:

Uso:

<?php
/* first caller */
 Who::callme();

/* list the entire list of calls */
Who::followme();

Fonte classe: https://github.com/augustowebd/utils/blob /master/Who.php

debug_backtrace()

Você pode querer olhar para debug_backtrace , ou talvez debug_print_backtrace .

A solução da Walltearer é excelente, especialmente se fechado em uma tag 'pré':

<pre>
<?php debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); ?>
</pre>

- que define as chamadas em linhas separadas, cuidadosamente numeradas

eu adaptei resposta de Don Briggs acima para usar o log de erro interno em vez de imprimir pública, que pode ser a sua grande preocupação quando se trabalha em um servidor ao vivo. Além disso, acrescentou mais algumas modificações, como opção para incluir caminho completo do arquivo em vez do nome básico (porque, poderia haver arquivos com o mesmo nome em diferentes caminhos), e também (para aqueles que necessitam dele) uma saída completa pilha nó:

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());
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top