2012-01-12 14 views
6

जारी रखें, मुझे पता है कि, इसकी परिभाषा के अनुसार, एक घातक अपवाद निष्पादन को मारना है, और इसे दबाया नहीं जाना चाहिए, लेकिन यहां समस्या है।एक घातक अपवाद पकड़ें और

मैं एक ऐसी स्क्रिप्ट चला रहा हूं जो डीबी में लगभग 10,000 पृष्ठों को स्क्रैप, पार्स और स्टोर करता है। इसमें कुछ घंटे लगते हैं, और दुर्लभ मामलों में (1000 में 1) एक पृष्ठ पार्सिंग में विफल रहता है और घातक अपवाद फेंकता है।

वर्तमान में, मैं यह कर रहा हूँ:

for ($i=0;$i<$count;$i++) 
     { 
      $classObject = $classObjects[$i];   

      echo $i . " : " . memory_get_usage(true) . "\n"; 

      $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);   
      $class = $parser->parseClassInfo($classDOM);      
      $dbmanager->storeClassInfo($class);   

      unset($classDOM,$class,$classObject);   
     }   

मैं की तरह

for ($i=0;$i<$count;$i++) 
{ 
    $classObject = $classObjects[$i];    
    echo $i . " : " . memory_get_usage(true) . "\n"; 

    try 
    { 
     $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);   
     $class = $parser->parseClassInfo($classDOM);     
     $dbmanager->storeClassInfo($class);   
     unset($classDOM,$class,$classObject);   
    } 
    catch (Exception $e) 
    { 
     //log the error here 
     continue; 
    } 
} 

कुछ कोड ऊपर fatal exceptions के लिए काम नहीं करता है कर सकते हैं।

क्या ऐसा कुछ करना संभव होगा: यदि मैंने मुख्य लूप को विधि में ले जाया है, और फिर register_shutdown_function से विधि को कॉल करें?

इस तरह:

Fatal error: Call to a member function find() on a non-object in ... 

मैं इस उपरोक्त संदेश जब एक पृष्ठ को पार्स करने योग्य नहीं है विधि मैं द्वारा की उम्मीद:

function do($start) 
{ 
    for($i=$start;$i<$count;$i++) 
    { 
     //do stuff here 
    } 
} 

register_shutdown_function('shutdown'); 

function shutdown() 
{ 
    do(); 
} 

यह संदेश है कि उत्पादन जब निष्पादन बंद हो जाता है उपयोग कर रहा हूँ मैं बस उस पृष्ठ को छोड़कर लूप के अगले पुनरावृत्ति पर जाने के साथ ठीक हूं।

+3

'घातक अपवाद' क्या है? आपका कैच (अपवाद $ ई) कैसे काम नहीं कर रहा है? – cspray

+1

दरअसल ..... क्या कोई ऐसा कुछ फेंक रहा है जो 'अपवाद' का विस्तार नहीं करता है? – Wrikken

+0

... इस मामले में, क्या आप सिर्फ '} पकड़ नहीं सकते ($ e) {'? – DaveRandom

उत्तर

10

घातक त्रुटियां घातक हैं और निष्पादन समाप्त होती हैं। यदि कोई घातक त्रुटि होती है तो इसके चारों ओर कोई रास्ता नहीं है। हालांकि, आपकी त्रुटि:

Fatal error: Call to a member function find() on a non-object in ...

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

if ($foo instanceof SomeObject) { 
    $foo->find(...); 
} else { 
    // something went wrong 
} 
+0

हां, यह इसे एक घातक त्रुटि – xbonez

+0

@mfonda पर कैसे बढ़ने की बजाय इसे संभालने का सबसे अच्छा तरीका प्रतीत होता है कि यह किस प्रकार है? –

1

मुझे लगता है कि एक शट डाउन फ़ंक्शन को पंजीकृत करने के साथ एक गलत त्रुटि "पकड़ने" का एकमात्र संभव तरीका है। लेनदेन में सभी (या शायद समूह) प्रश्नों को जोड़ना याद रखें और कुछ विफल होने पर, उन्हें स्थिरता सुनिश्चित करने के लिए शायद उन्हें वापस रोल करें।

+1

एक घातक त्रुटि पर, मैं कृपा से बाहर निकलने की तलाश नहीं कर रहा हूं (साफ़ करें, रोलबैक लेनदेन और फिर बाहर निकलें)। मैं त्रुटि लॉग इन करना जारी रखता हूं और जारी रखता हूं। क्या यह संभव है? मुझे लगता है कि ऐसा मौका है कि यह नहीं है। – xbonez

+1

इस लिंक को देखें http://www.php.net/manual/en/function.register-shutdown-function.php, उनके द्वारा बनाए गए संदेशों की जांच करें, उनमें से कुछ आपकी समस्या से संबंधित हैं। लेकिन आपको अपने कोड – guiman

6

सबसे पहले, exceptions और errors के बीच एक अलग अंतर है। आपने जो सामना किया वह त्रुटि है, अपवाद नहीं। आपके संदेश के आधार पर और जिस समस्या को आपने पोस्ट किया है वह उस चीज के साथ है जिसे आपने अपने प्रश्न में नहीं रखा है। आप find() पर कॉल करने की कोशिश कर रहे हैं? खैर, वह चर एक वस्तु नहीं है। घातक त्रुटियों को फँसाने और इसे अनदेखा करने का कोई तरीका नहीं है, आपको यह पता लगाना चाहिए कि आप find() को गैर-ऑब्जेक्ट पर कहां कॉल कर रहे हैं और इसे ठीक करें।

+0

में जितना संभव हो उतना इरॉस से बचने का प्रयास करना चाहिए। मैं जिस एचटीएमएल डोम पार्सर लाइब्रेरी का उपयोग कर रहा हूं, वह ऑब्जेक्ट (पृष्ठ की डीओएम संरचना) देता है, और मैं उस ऑब्जेक्ट-> find() 'को खोजने के लिए उपयोग करता हूं कुछ तत्व जब कोई पृष्ठ पार्स-सक्षम नहीं होता है, तो यह ऑब्जेक्ट वापस नहीं करता है और इस प्रकार 'ऑब्जेक्ट-> ढूंढें()' घातक त्रुटि फेंकता है। मुझे लगता है कि मैं 'find()' – xbonez

+1

@xbonez को कॉल करने से पहले 'is_object()' चेक डाल सकता हूं, जो आपकी समस्या का उत्तर होगा, क्योंकि डोम पार्सर विफल होने से खुद को घातक त्रुटि नहीं होगी। आप नीचे दिए गए @mfonda द्वारा सुझाए गए 'exampleof' ऑपरेटर का भी उपयोग कर सकते हैं। – DaveRandom

+2

@xbonez यह एक विकल्प है। या आप ['NullObject'] (http://sourcemaking.com/design_patterns/null_object) डिज़ाइन पैटर्न को कार्यान्वित कर सकते हैं। असल में आप एक कार्यान्वयन सेट करते हैं कि जब आप '$ ऑब्जेक्ट-> ढूंढें()' कहते हैं तो यह एक खाली ऑब्जेक्ट देता है जिसे आप अभी भी विधियों पर कॉल कर सकते हैं। यह सुनिश्चित करेगा कि आपके पास हमेशा एक विधि कॉल करने के लिए एक ऑब्जेक्ट है और आपको उन ऑब्जेक्ट चेक करने की आवश्यकता नहीं है। – cspray

1

मैं यह करने के लिए इसी तरह की एक समस्या पड़ा है, और मैंने पाया एक is_object का उपयोग कर() कॉल कि खोजने से पहले() कॉल आपको घातक त्रुटि से बचने की अनुमति देता है।

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