2010-12-10 7 views
31

the comment on this answer के अनुसार PHP में घातक त्रुटियों को संभालें shutdown function के माध्यम से घातक त्रुटियों को पकड़ना संभव है जिसे set_error_handler() का उपयोग करके पकड़ा नहीं जा सकता है।रजिस्टर_शूटडाउन_फंक्शन()

हालांकि, मुझे यह पता नहीं लगाया जा सकता कि यह निर्धारित करने के लिए कि घातक त्रुटि या स्क्रिप्ट के अंत तक पहुंचने के कारण शट डाउन हुआ है या नहीं।

इसके अतिरिक्त, डीबग बैकट्रैक फ़ंक्शन शटडाउन फ़ंक्शन में निष्क्रिय हो जाते हैं, जिससे स्टैक ट्रेस लॉगिंग के लिए यह बहुत बेकार हो जाता है जहां घातक त्रुटि हुई।

तो मेरा सवाल यह है कि: उचित बैकट्रैक बनाने की क्षमता रखते हुए घातक त्रुटियों (विशेष रूप से अपरिभाषित फ़ंक्शन कॉल) पर प्रतिक्रिया करने का सबसे अच्छा तरीका क्या है?

उत्तर

54

यह मेरे लिए काम करता है:

function shutdown() { 
    $error = error_get_last(); 
    if ($error['type'] === E_ERROR) { 
     // fatal error has occured 
    } 
} 

register_shutdown_function('shutdown'); 

spl_autoload_register('foo'); 
// throws a LogicException which is not caught, so triggers a E_ERROR 

हालांकि, आप शायद यह पहले से ही पता है, लेकिन अभी सुनिश्चित करने के लिए: यदि आप किसी भी तरह से एक E_ERROR से उबरने नहीं कर सकते।

पश्व-अनुरेखन का सवाल है, आप नहीं कर सकते ... :(एक गंभीर त्रुटि के ज्यादातर मामलों में, विशेष रूप से अपरिभाषित समारोह त्रुटियों, क्या तुम सच में इसकी आवश्यकता नहीं है। फ़ाइल/लाइन जहां यह हुआ है Pinpointing पर्याप्त है। बैकट्रैक उस मामले में अप्रासंगिक है।

+0

ग्रेट स्निपेट! मैं 'इको' त्रुटि एमएसजी का भी उपयोग करता हूं: ["। $ त्रुटि ['message']।]] लाइन पर: ["। $ त्रुटि ['लाइन']। "] \ R \ n"; 'नवीनीकृत:) –

7

रजिस्टर_शूटडाउन_फंक्शन के साथ घातक त्रुटि और उचित एप्लिकेशन शटडाउन के बीच अंतर करने का एक तरीका है अपने प्रोग्राम की अंतिम पंक्ति के रूप में निरंतर परिभाषित करना, और फिर जांचें कि निरंतर परिभाषित किया गया है या नहीं:

function fatal_error() { 
if (! defined(PROGRAM_EXECUTION_SUCCESSFUL)) { 
     // fatal error has occurred 
    } 
} 

register_shutdown_function('fatal_error'); 

define('PROGRAM_EXECUTION_SUCCESSFUL', true); 

यदि कार्यक्रम अंत तक पहुंचता है, तो यह हो सकता है एक घातक त्रुटि का सामना नहीं किया है, इसलिए हम जानते हैं कि निरंतर परिभाषित होने पर फ़ंक्शन को न चलाएं।

error_get_last() घातक त्रुटि के बारे में सारी जानकारी के साथ एक सरणी है जिसे आपको डीबग करने की आवश्यकता होनी चाहिए, हालांकि इसका उल्लेख नहीं किया गया है, जैसा कि इसका उल्लेख किया गया है।

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

4

बस एक अच्छी चाल वर्तमान error_handler विधि प्राप्त करने के लिए =)

<?php 
register_shutdown_function('__fatalHandler'); 
function __fatalHandler() 
{ 
    $error  = error_get_last(); 

    //check if it's a core/fatal error, otherwise it's a normal shutdown 
    if($error !== NULL && $error['type'] === E_ERROR) { 
     //Bit hackish, but the set_exception_handler will return the old handler 
     function fakeHandler() { } 
     $handler = set_exception_handler('fakeHandler'); 
     restore_exception_handler(); 
     if($handler !== null) { 
      call_user_func($handler, new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line'])); 
     } 
     exit; 
    } 
} 
?> 

इसके अलावा मैं नोट करने के लिए अगर आप फोन है कि

<?php 
ini_set('display_errors', false); 
?> 

Php बंद हो जाता है त्रुटि प्रदर्शित wan't, अन्यथा त्रुटि पाठ आपके त्रुटि हैंडलर

-1

से पहले क्लाइंट को भेजा जाएगा, इसके लिए मैं "ob_start" का उपयोग करता हूं।

function fatal_error_handler($buffer) { 
    if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs)) { 
     //Your code 
    } 
    return $buffer; 
} 
ob_start("fatal_error_handler"); 
+0

यह एक पैरामीटर पर संकेत दिया जा रहा है लेकिन regex का उपयोग कर जांच करने की एक कम कुशल विधि है।स्वीकृत उत्तर स्पष्ट और अधिक कुशल दोनों है। – pcnate