PHP कॉल स्टैक प्रिंट करें


257

मैं PHP में कॉल स्टैक को प्रिंट करने का एक तरीका ढूंढ रहा हूं।

बोनस अंक अगर फ़ंक्शन IO बफर को फ्लश करता है।



12
... लेकिन ये प्रतिक्रियाएं बेहतर हैं।
बेन

जवाबों:


123

यदि आप एक बैकट्रेस उत्पन्न करना चाहते हैं, तो आप खोज रहे हैं 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"
  }
}


वे जाहिरा तौर पर I / O बफर को फ्लश नहीं करेंगे, लेकिन आप खुद के साथ flushऔर / या ऐसा कर सकते हैं ob_flush

("और / या"; ;-) का पता लगाने के लिए पहले एक का मैनुअल पेज देखें


7
यह नियमित रूप से मेरी php स्मृति से बाहर चलाता है। मैं टोबियास के समाधान की सलाह देता हूं।
पेदी

अगर आपको पढ़ने / समझने में मुश्किल हो रही है, तो मैं भी
टोबियास के

1
@ इसमें सभी को वैकल्पिक DEBUG_BACKTRACE_IGNORE_ARGSपैरामीटर प्रदान करना है; यह उन्हें कार्यात्मक रूप से समकक्ष बनाता है(new \Exception())->getTraceAsString()

565

से अधिक पठनीय 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}"

50
धिक्कार है, यह इतना बेहतर है, वे इसे डिबग_प्रिंट_बैकट्रेस () के लिए डिफ़ॉल्ट आउटपुट क्यों नहीं बना सके? उन लोगों के लिए एक बूलियन पैरामीटर "रिटर्नट्रेस" जोड़ा जा सकता था जो इसे एक चर में चाहते हैं, गूंज नहीं, और यह सही होगा!
jurchiks

1
मुझे नहीं पता कि मैं कितने महीनों से यह जानने की कोशिश कर रहा था कि ऐसा कभी नहीं सोचा था कि यह काम करेगा
WojonsTech

यह समाधान भी एक सरणी के रूप में debug_backtrace () के आउटपुट को कैप्चर करने से कम मेमोरी लेने के लिए प्रतीत होता है और फिर इसे print_r () का उपयोग करके प्रिंट किया जाता है, जो कि मैं तब तक कर रहा था जब तक मैंने यह नहीं देखा!
पीटर

5
मैं debug_backtraceस्टैकट्रेस में केवल पहले स्तर को वापस करने के लिए सीमित करने के लिए एक रास्ता ढूंढ रहा था - यह समाधान मेरे लिए काम करता है। धन्यवाद!
अक्‍सर

3
@ print_rऔर सभी संदेशों को बरकरार रखेगा।
mopo922

41

ट्रेस लॉग करने के लिए

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

धन्यवाद @Tobiasz


35

Backtrace में ढेर सारा कचरा होता है जिसकी आपको जरूरत नहीं है। यह बहुत लंबा है, पढ़ने में मुश्किल है। तुम सब usuall कभी चाहता है "क्या कहा जाता है जहां से?" यहाँ एक सरल स्थिर फ़ंक्शन समाधान है। मैं इसे आमतौर पर 'डिबग' नामक कक्षा में रखता हूं, जिसमें मेरे सभी डीबगिंग उपयोगिता कार्य शामिल हैं।

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


33

अजीब है कि किसी ने इस तरह पोस्ट नहीं किया:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

यह वास्तव में कचरे के बिना बैकट्रेस प्रिंट करता है - बस किस विधि को बुलाया गया था और कहां।


2
वास्तव में, वास्तव में मुख्य मतदान समाधान के बराबर है, और कम। धन्यवाद
brunetton

9

यदि आप एक स्टैक ट्रेस चाहते हैं, जो कि 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() 

2
या बस$e = new Exception; echo $e->getTraceAsString();
ब्रैड केंट

ब्रैड, वह समाधान स्टैक ट्रेस से अंतिम आइटम को नहीं निकालता है ताकि आप नए अपवाद के कारण होने वाले ट्रेस आइटम को न दिखाएं
ट्रॉयसेवेन

8
var_dump(debug_backtrace());

क्या यह वही है जो आप चाहते हैं?



4

phptrace PHP स्टैक को प्रिंट करने के लिए कभी भी जब आप कोई एक्सटेंशन स्थापित किए बिना एक महान उपकरण है।

Phptrace के दो प्रमुख कार्य हैं: पहला, 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 

क्या कोई विंडोज संस्करण है?
जॉनी

मुझे पसंद है कि मैमोरी एड्रेस यहाँ दिखाया गया है .. यह मददगार हो सकता है
टायलर माइल्स

3

उपयोग debug_backtraceक्या कार्य करता है और पद्धतियों को बुलाया गया था और क्या फ़ाइलें शामिल किया गया था कि बिंदु है जहां के लिए नेतृत्व की एक नामों को प्राप्त करने debug_backtraceबुलाया गया है।





1

वाल्टेयर का समाधान उत्कृष्ट है, खासकर यदि एक 'पूर्व' टैग में संलग्न है:

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

- जो अलग-अलग लाइनों पर कॉल सेट करता है, बड़े करीने से गिना जाता है


0

मैंने सार्वजनिक मुद्रण के बजाय आंतरिक त्रुटि लॉगिंग का उपयोग करने के लिए ऊपर डॉन ब्रिग्स के उत्तर को अनुकूलित किया है , जो लाइव सर्वर पर काम करते समय आपकी बड़ी चिंता हो सकती है। इसके अलावा, मूल नाम के बजाय पूर्ण फ़ाइल पथ को शामिल करने के विकल्प के रूप में कुछ और संशोधनों को जोड़ा गया है (क्योंकि, अलग-अलग रास्तों में एक ही नाम वाली फाइलें हो सकती हैं), और यह भी (जिनके लिए इसकी आवश्यकता है) एक पूर्ण नोड स्टैक आउटपुट:

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());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.