سؤال

أنا أبحث عن طريقة لطباعة مكدس الاستدعاءات في PHP.

نقاط المكافأة إذا كانت الوظيفة تقوم بمسح المخزن المؤقت للإدخال والإدخال.

هل كانت مفيدة؟

المحلول

إذا كنت ترغب في إنشاء أثر خلفي، فأنت تبحث عنه 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"
  }
}


من الواضح أنهم لن يقوموا بمسح المخزن المؤقت للإدخال/الإخراج، ولكن يمكنك القيام بذلك بنفسك باستخدام flush و/أو ob_flush.

(راجع الصفحة اليدوية للصفحة الأولى لمعرفة سبب ظهور "و/أو" ؛-))

نصائح أخرى

وأكثر قابلية للقراءة من 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}"

لتسجيل التتبع

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

وبفضلTobiasz

والمتتبع الخلفي مقالب مجموعة كبيرة من القمامة التي لا تحتاج. ما يتطلبه الأمر هو طويل جدا، من الصعب قراءة. كل ما 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)
==================================================

والغريب أن لا أحد نشر بهذه الطريقة:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

وهذا يطبع الواقع المتتبع الخلفي دون القمامة - فقط ما كان يسمى طريقة وأين

.

إذا كنت ترغب في تتبع المكدس التي تبدو مشابهة جدا لكيفية صيغ فب باستثناء تتبع المكدس من استخدام هذه الوظيفة كتبت:

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

هل هذا تفعل ما تريد؟

debug_print_backtrace . أعتقد أنك يمكن أن نطلق flush بعد ذلك إذا كنت تريد.

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 

استخدم debug_backtrace للحصول على المتتبع الخلفي من ما هي الوظائف وأساليب قد دعا وما هي الملفات كان وشملت التي أدت إلى النقطة التي كان يطلق debug_backtrace.

ويرجى إلقاء نظرة على هذا تيلس الدرجة، قد تكون مفيدة:

والاستعمال:

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

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

والطبقة المصدر: https://github.com/augustowebd/utils/blob /master/Who.php

وdebug_backtrace()

وقد ترغب في النظر في debug_backtrace أو ربما <لأ href = "HTTP: // www.php.net/debug_print_backtrace "يختلط =" نوفولو noreferrer "> debug_print_backtrace .

يعد حل Walltearer ممتازًا، خاصة إذا كان مرفقًا بعلامة "pre":

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

- الذي يحدد المكالمات على خطوط منفصلة ومرقمة بشكل أنيق

الجواب

ولقد تكيفت دون بريجز إلى ما فوق لاستخدام تسجيل خطأ داخلي بدلا من الطباعة العامة، والتي قد تكون لديك قلق كبير عند العمل على الخادم الحية. أيضا، وأضاف بضعة تعديلات مثل الخيار لتضمين مسار ملف كامل بدلا من اسم الأساسي (لأنه يمكن أن يكون هناك ملفات مع نفس الاسم في مسارات مختلفة)، وأيضا (بالنسبة لأولئك الذين يحتاجون اليها) كامل الانتاج العقدة كومة:

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());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top