it-swarm.com.de

Drucken PHP Stack anrufen

Ich suche nach einer Möglichkeit, den Aufrufstack in PHP zu drucken. 

Bonuspunkte, wenn die Funktion den IO -Puffer leert.

223
Justin

Wenn Sie eine Rückverfolgung erzeugen möchten, suchen Sie nach debug_backtrace und/oder debug_print_backtrace.


Der erste bekommt zum Beispiel ein Array wie dieses (zitiert das Handbuch):

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


Sie werden den E/A-Puffer anscheinend nicht leeren, aber Sie können dies selbst mit flush und/oder ob_flush.

(siehe Handbuchseite der ersten Seite, um herauszufinden, warum das "und/oder" ;-))}

114
Pascal MARTIN

Lesbarer als 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}"
489
Tobiasz Cudnik

So protokollieren Sie die Ablaufverfolgung

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

Danke @Tobiasz

37
Sydwell

Backtrace Dumps eine Menge Müll, die Sie nicht brauchen. Es dauert sehr lange und ist schwer zu lesen. Alles, was Sie normalerweise wollen, ist "Was nannte was von wo?" Hier ist eine einfache statische Funktionslösung. Normalerweise stelle ich es in eine Klasse namens 'debug', die alle meine Debugging-Funktionen enthält.

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

Sie nennen es so:

debugUtils::callStack(debug_backtrace());

Und es produziert Ausgabe wie folgt:

==================================================
 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)
==================================================
30
Don Briggs

Seltsam, dass niemand so geschrieben hat:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

Dies druckt tatsächlich eine Rückverfolgung ohne den Müll - genau welche Methode wurde wo aufgerufen.

29
WallTearer

Wenn Sie eine Stack-Ablaufverfolgung wünschen, die der Formatierung der Ausnahmestapel-Ablaufverfolgung sehr ähnelt, verwenden Sie die von mir beschriebene Funktion: 

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

Dadurch wird eine Stapelablaufverfolgung zurückgegeben, die folgendermaßen formatiert ist: 

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

Tun das, was du willst?

7
inkedmn

Siehe debug_print_backtrace . Ich denke, Sie können später flush aufrufen, wenn Sie möchten.

6
Martin Geisler

phptrace ist ein großartiges Werkzeug zum Drucken des PHP - Stapels, wann immer Sie möchten, ohne Erweiterungen zu installieren. 

Es gibt zwei Hauptfunktionen von phptrace: erstens den Call-Stack von PHP, der nichts zu installieren braucht, zweitens, Ablaufverfolgungs-PHP-Ausführungsflüsse, die die von ihm bereitgestellte Erweiterung installieren müssen.

wie folgt:

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

Verwenden Sie debug_backtrace , um zu erfahren, welche Funktionen und Methoden aufgerufen wurden und welche Dateien enthalten waren, die zu dem Punkt führten, an dem debug_backtrace aufgerufen wurde.

3
Gumbo

bitte schauen Sie sich diese utils-Klasse an, vielleicht hilfreich:

Verwendungszweck: 

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

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

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

2
augustowebd

debug_backtrace()

1
pix0r

Vielleicht möchten Sie nach debug_backtrace oder vielleicht debug_print_backtrace suchen.

1
Rob

Die Lösung von Walltearer ist ausgezeichnet, besonders wenn sie in einem "pre" -Tag enthalten ist:

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

- die die Anrufe auf separaten Leitungen mit sauberer Nummerierung festlegt

0
Geoff Kendall

Ich habe Don Briggs 'Antwort so angepasst, dass anstelle des öffentlichen Druckens die interne Fehlerprotokollierung verwendet wird, was bei der Arbeit an einem Live-Server möglicherweise ein großes Problem ist. Außerdem wurden einige weitere Modifikationen hinzugefügt, z. B. die Option, den vollständigen Dateipfad anstelle des Basisnamens einzuschließen (da möglicherweise Dateien mit demselben Namen in unterschiedlichen Pfaden vorhanden sind) und (für diejenigen, die dies erfordern) eine vollständige Ausgabe des Knotenstapels:

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());
0
dev101