PHP Çağrı Yığını Yazdır


Yanıtlar:


123

Eğer bir geri iz oluşturmak istiyorsanız debug_backtraceve / veya arıyoruz debug_print_backtrace.


Birincisi, örneğin, size böyle bir dizi alır (kılavuzdan alıntı yaparak) :

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


Görünüşe göre I / O tamponunu temizlemeyecekler, ancak bunu kendiniz flushve / veya ile yapabilirsiniz ob_flush.

("ve / veya" ;-) nedenini bulmak için ilkinin kılavuz sayfasına bakın)


7
bu düzenli benim php bellek yetersiz yapar. Tobiasz'in çözümünü öneriyorum.
peedee

Okumayı / anlamayı zor buluyorsanız,
Tobiasz'ın

1
@peedee, isteğe bağlı DEBUG_BACKTRACE_IGNORE_ARGSparametrelerden birini sağlamaktır ; Bu onları işlevsel olarak eşdeğer yapar(new \Exception())->getTraceAsString()

567

Daha okunabilir 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
Kahretsin, bu çok daha iyi, neden bunu debug_print_backtrace () için varsayılan çıktı haline getiremediler? Yankı değil, bir değişken isteyenler için bir boole parametresi "returnTrace" ekleyebilirdi ve mükemmel olurdu!
jurchiks

1
Kaç aydır işe yarayacağını hiç düşünmemeye nasıl çalıştığımı bilmiyorum
WojonsTech

Bu çözüm ayrıca bir dizi olarak debug_backtrace () çıktısını yakalamak ve daha sonra bunu görene kadar yaptığım şey olan print_r () kullanarak yazdırmaktan daha az bellek alıyor gibi görünüyor!
Peter

5
Ben debug_backtracesadece stacktrace ilk seviyeye dönmek için sınırlamak için bir yol arıyordu - bu çözüm benim için işi yapar. Teşekkür ederim!
ankr

3
@Andrew print_rtüm mesajları saklayacak .
mopo922

41

İzi günlüğe kaydetmek için

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

Teşekkürler @Tobiasz


35

Backtrace ihtiyacınız olmayan bir sürü çöpü boşaltır. Çok uzun, okunması zor. Her zaman istediğiniz tek şey "nereden ne denir?" İşte basit bir statik fonksiyon çözümü. Genellikle tüm hata ayıklama yardımcı programı işlevlerini içeren 'debug' adlı bir sınıfa koyarım.

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

Buna şöyle diyorsunuz:

debugUtils::callStack(debug_backtrace());

Ve şöyle çıktı üretir:

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

Kimsenin bu şekilde yayınlamaması garip:

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

Bu aslında çöp olmadan geri iz yazdırır - tam olarak hangi yöntemin adı ve nerede.


2
Gerçekten de, ana oylanan çözüme gerçekten eşdeğer ve daha kısa. Thanks
brunetton

9

Ben php istisna yığın iz biçimleri nasıl bu yazıyı kullanmak daha çok nasıl görünüyor benzer bir yığın izleme istiyorsanız yazdım:

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

Bu, şu şekilde biçimlendirilmiş bir yığın izini döndürür:

#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
ya da sadece$e = new Exception; echo $e->getTraceAsString();
Brad Kent

Brad, bu çözüm son öğeyi yığın izlemesinden kaldırmaz, böylece yeni
İstisna'nın

8
var_dump(debug_backtrace());

Bu istediğini yapıyor mu?



4

phptrace , herhangi bir uzantı yüklemeden istediğiniz zaman PHP yığınını yazdırmak için harika bir araçtır.

Phptrace iki büyük işlevi vardır: ilk, hiçbir şey yüklemek gerekmez PHP baskı çağrı yığını, ikincisi, tedarik uzantısını yüklemek için gereken php yürütme izleme akışları.

aşağıdaki gibi:

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

Bir Windows sürümü var mı?
johnny

Ben bellek adresi burada gösterilen gibi .. Bu yardımcı olabilir
Tyler Miles

3

debug_backtraceHangi işlev ve yöntemlerin çağrıldığı ve hangi dosyaların dahil debug_backtraceedildiğinin çağrıldığı noktaya ilişkin bir geri izleme almak için kullanın .





1

Walltearer'ın çözümü, özellikle bir 'ön' etikete eklenmişse mükemmeldir:

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

- aramaları düzgün bir şekilde numaralandırılmış ayrı hatlarda düzenler


0

Don Briggs'in yukarıdaki cevabını , canlı bir sunucu üzerinde çalışırken büyük endişeniz olabilecek, genel baskı yerine dahili hata günlüğü kullanacak şekilde uyarladım . Ayrıca, temel ad yerine tam dosya yolunu dahil etme seçeneği gibi birkaç değişiklik daha yaptı (çünkü farklı yollarda aynı ada sahip dosyalar olabilir) ve ayrıca (ihtiyaç duyanlar için) tam bir düğüm yığını çıktısı eklendi:

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());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.