2011-01-03 26 views
12

मुझे लगता है कि कभी-कभी debug_backtrace() में कॉल के लिए लाइन नंबर शामिल नहीं है। क्या इसका कोई कारण है और इसके लिए सही करने का कोई तरीका क्यों है?debug_backtrace() कभी-कभी लाइन नंबर सहित क्यों नहीं है?

अग्रिम धन्यवाद।

पीएस और हां, जिन कॉलों के लिए यह लाइन नंबर छोड़ना है, वे मेरे स्वयं के कोड हैं, आंतरिक PHP कोड नहीं।

+4

दिलचस्प। क्या आप एक उदाहरण पोस्ट कर सकते हैं? – deceze

+1

क्या यह शायद एक अपवाद, बंद, evaled कोड, टिक कार्य, त्रुटि हैंडलर, (मूल रूप से कोई भी कोड जो सामान्य निष्पादन ढेर से संचालित है) के अंदर है? इसके अलावा, मैं नहीं देख सकता कि आपको लाइन नंबर क्यों नहीं मिलेगा (कम से कम उदाहरण के बिना) ... – ircmaxell

+0

@deceze - कोड एक उदाहरण पोस्ट करने के लिए बहुत जटिल है। काश मैं कर सकता था लेकिन पोस्ट करने के लिए पर्याप्त कुछ आसान पहचानने में घंटों या अधिक समय लगेगा और यह उस समय खर्च करने के लिए मेरे लिए बड़ी समस्या नहीं है। – MikeSchinkel

उत्तर

4

मैं इस एक PHP Bug

डिबग पश्व-अनुरेखन रूप में सूचीबद्ध है लगता है फ़ाइल नाम और स्क्रिप्ट बुलाने की lineno को दर्शाता है। फ़ंक्शन को आंतरिक फ़ंक्शन के अंदर से कॉल किया जाता है (कॉलबैक के रूप में हो सकता है) कोई फ़ाइल नाम और लिनेनो सेट नहीं किया जा सकता है।

+0

उस लिंक को ट्रैक करने के लिए धन्यवाद। मुझे नहीं लगता कि कोड को आंतरिक फ़ंक्शन द्वारा बुलाया जा रहा है लेकिन मैं जांच करूंगा। – MikeSchinkel

9

कोड निम्नलिखित पर विचार करें:

<? 
class BtTest 
{ 
    public function getTheItem() 
    { 
    var_dump(debug_backtrace(false)); 
    $bt = debug_backtrace(false); 
    return $bt[1]; 
    } 

    public function __call($methodName, $methodArgs) 
    { 
    return $this->getTheItem(); 
    } 
} 

$o = new BtTest(); 
$bti = $o->test(); 

assert('array_key_exists("function", $bti)'); 
assert('array_key_exists("line", $bti)'); 
assert('array_key_exists("file", $bti)'); 

ऊपर के उदाहरण के निष्पादन के उत्पादन निम्नलिखित उत्पन्न:

array(3) { 
    [0]=> 
    array(6) { 
    ["file"]=> 
    string(53) "/somewhere/in/the/filesystem/tests/bt-test-so.php" 
    ["line"]=> 
    int(13) 
    ["function"]=> 
    string(10) "getTheItem" 
    ["class"]=> 
    string(6) "BtTest" 
    ["type"]=> 
    string(2) "->" 
    ["args"]=> 
    array(0) { 
    } 
    } 
    [1]=> 
    array(4) { 
    ["function"]=> 
    string(6) "__call" 
    ["class"]=> 
    string(6) "BtTest" 
    ["type"]=> 
    string(2) "->" 
    ["args"]=> 
    array(2) { 
     [0]=> 
     &string(4) "test" 
     [1]=> 
     &array(0) { 
     } 
    } 
    } 
    [2]=> 
    array(6) { 
    ["file"]=> 
    string(53) "/somewhere/in/the/filesystem/tests/bt-test-so.php" 
    ["line"]=> 
    int(18) 
    ["function"]=> 
    string(4) "test" 
    ["class"]=> 
    string(6) "BtTest" 
    ["type"]=> 
    string(2) "->" 
    ["args"]=> 
    array(0) { 
    } 
    } 
} 
PHP Warning: assert(): Assertion "array_key_exists("line", $bti)" failed in /somewhere/in/the/filesystem/tests/bt-test-so.php on line 21 
PHP Warning: assert(): Assertion "array_key_exists("file", $bti)" failed in /somewhere/in/the/filesystem/tests/bt-test-so.php on line 22 

पहले पश्व-अनुरेखन मद (सूचकांक 0) परोक्ष रूप से कहते हैं (line और file आइटम के माध्यम से) कि विधि __call विधि से विधि को बुलाया गया था।

दूसरा पश्व-अनुरेखन मद (सूचकांक 1) का कहना है कि __call विधि से कहीं (line और file आइटम अनुपलब्ध) कहा जाता था।

तीसरा बैकट्रैक आइटम (अनुक्रमणिका 2) कहता है कि test विधि को स्क्रिप्ट के वैश्विक दायरे से बुलाया गया था।

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

तो ऐसा लगता है कि debug_backtrace फ़ंक्शन के कोड (या कम से कम बनाए रखने) के लिए ज़िम्मेदार डेवलपर (ओं) को इसे बग के रूप में नहीं समझता है या इसे ठीक करने का कोई आसान तरीका नहीं है। कुछ जगह धारक मूल्यों के साथ line और file आइटम भरना ठीक होगा (उदा। <unknown-file> और 0 या यहां तक ​​कि नल) और दस्तावेज़ में जोर दें। जब तक कोई उन्हें सफलतापूर्वक करने के लिए उन्हें विश्वास दिलाएगा, तो आपको बस अपने कोड में विशेष केस को संभालना होगा।

मैंने ऊपर लिखा है कि समारोह के अजीब व्यवहार की मेरी समझ को साझा करने के लिए।किसी एक से थोड़ा बेहतर दुनिया के लिए लड़ने की इच्छा है, तो यहां कुछ संबंधित बग रिपोर्ट करने के लिए लिंक कर रहे हैं:

सबसे पुरानी रिपोर्ट 2003 से है, इसलिए आपको नहीं करना चाहिए एक फास्ट फिक्स पर गिनें :)

+0

विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद। उत्कृष्ट कार्य! – MikeSchinkel

1

किसी भी "बग", "फीचर" के बावजूद, जो कुछ भी PHP बनाए रखने वाले लोग कहना चाहते हैं, डीबग_बैकट्रैस() काम नहीं करेगा जैसा मैं उम्मीद करता हूं।

यहाँ मेरी समाधान (यह बदसूरत है, लेकिन यह मेरे लिए काम करता है):

function dbg($msg="") 
{ 
    ob_start(); 
    debug_print_backtrace(0,1); 
    $_ = ob_get_clean(); 
    list($ignore,$line_number) = explode(':', $_); 
    $line_number += 0; 

    $backtrace = debug_backtrace(0); 
    extract($backtrace[1]); 
    echo "<pre>$class::$function($msg) : $line_number</pre>"; 
} 

पीएचपी समारोह debug_print_backtrace (0,1); कुछ इस तरह का उत्पादन करेगा: केवल ट्रेस इको

# 0 dbg-> पिंग (290) [/path/to/filename.php:290]

पर कहा जाता है यह बाद से, मैं ob_get_clean करने के लिए है() यह एक स्ट्रिंग के रूप में। तब मैं इसे पार्स करता हूं।

मेरे कार्यान्वयन में, मैं केवल कॉलिंग फ़ंक्शन से कक्षा, फ़ंक्शन, लाइन नंबर और वैकल्पिक रूप से एक स्ट्रिंग संदेश जानना चाहता हूं। debug_backtrace() कक्षा और कार्य सही तरीके से प्रदान करता है, लेकिन लाइन-संख्या नहीं। यही कारण है कि मुझे debug_print_backtrace() फ़ंक्शन से लाइन नंबर प्राप्त करना होगा।

बोनस अंक के लिए .... यह कैसे है कि debug_print_backtrace() फ़ंक्शन लाइन नंबर "जानता है", लेकिन debug_backtrace() [कभी-कभी] नहीं करता है, आह ??? ... यह एक रहस्य है ...

संबंधित मुद्दे