2012-12-19 6 views
8

मेरे पास एक php स्क्रिप्ट निष्पादन के दौरान कहती है कि स्क्रिप्ट अपवाद फेंकता है। मैं चाहता हूं कि मेरा PHP फिर से शुरू हो जाए जहां से यह छोड़ा गया था (जहां उसने अपवाद फेंका था)।अपवाद के बाद निष्पादन स्क्रिप्ट में PHP को फिर से शुरू करें

क्या मुझे कोड के "पकड़" भाग में एक ही निष्पादन कोड रखना चाहिए?

उदाहरण पर, है जोड़ता mySQL के लिए यह विफल कनेक्शन

function someCode(){ 
     $pdostmt = $this->prepare($this->sql); 
     if($pdostmt->execute($this->bind) !== false) { 
      if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) 
       return $pdostmt->fetchAll($this->fetchOption); 
      elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) 
       return $pdostmt->rowCount(); 
    } 
    try { 
     someCode(); 
     } 
    } catch (PDOException $e) { 
     //re-execute same code as within the try clause? 
     someCode(); 
    } 
+2

क्या आप ऐसा करने का प्रयास कर सकते हैं जो आप करने का प्रयास करते हैं? शायद यह refactoring मदद मिलेगी। –

+5

कोड, या ऐसा नहीं हुआ। – moonwave99

+0

ए 'try' ब्लॉक में कई कथन शामिल हो सकते हैं। यह पता लगाना संभव है कि किसने अपवाद को ट्रिगर किया लेकिन यह मामूली नहीं है। आप क्या खत्म करने की कोशिश कर रहे हैं? –

उत्तर

21

पहले एक बनाना चाहिए स्पष्ट है कि एक अपवाद केवल घातक है अगर यह पकड़ा नहीं है। अपवाद को पकड़ना रोकथाम स्क्रिप्ट निष्पादन नहीं करता है। यह केवल प्रयास ब्लॉक में स्टैक फ्रेम को रोकता है और कैच ब्लॉक पर नियंत्रण स्थानांतरित करता है। वहां से आपकी स्क्रिप्ट सामान्य के रूप में निष्पादित जारी रहेगी।

अपवाद को पकड़ने तक यहाँ हम अभी भी सामान्य स्क्रिप्ट निष्पादन को फिर से शुरू करने के बाद अपवाद पकड़ा है ...

try { 
    echo "Try...\n"; 
    throw new Exception("This is an exception"); 
} catch(Exception $e) { 
    echo "Exception caught with message: " . $e->getMessage() . "\n"; 
} 

echo "Script is still running..."; 

क्या आप चाहते हो सकता है एक exception handler है। अपवाद संचालक का उपयोग करने के लिए इतना है कि आप try/catch ब्लॉकों में प्रत्येक अपवाद आप निम्नलिखित कर सकते हैं संभाल करने के लिए नहीं है ...

function myExceptionHandler($e) { 
    echo "Uncaught exception with message: " , $e->getMessage(), "\n"; 
} 

set_exception_handler('myExceptionHandler'); // Registers the exception handler 

throw new Exception("This is Exception 1"); 
throw new Exception("This is Exception 2"); 
throw new Exception("This is Exception 3"); 
echo "The script is still running..."; 

संपादित करें: आपके सवाल का स्पष्ट करने के बाद मुझे लगता है कि मैं यह लिखा होना चाहिए जो आप चाहते हैं वह अपवाद हैंडलर नहीं है, लेकिन आप वास्तव में अपवादों का उपयोग नहीं करना चाहते हैं। आप जो करने की कोशिश कर रहे हैं उसे अपवादों को फेंकने की आवश्यकता नहीं है। यदि आप जो करना चाहते हैं तो पीडीओ को अपवाद मोड में न डालें, बस उस तरह की त्रुटि को संभालें। अपवाद का उपयोग केवल असाधारण त्रुटियों को संभालने के लिए किया जाना चाहिए। अपवाद का पूरा बिंदु यह सुनिश्चित करना है कि आप अपना वादा रखें। उदाहरण के लिए, यदि आपका कार्य वादा करता है कि यह हमेशा एक पीडीओएसएटेमेंट ऑब्जेक्ट लौटाएगा और ऐसा कोई मामला है जहां यह संभवतः ऐसा नहीं कर सकता है, तो यह अपवाद को फेंकने के लिए समझ में आता है। इससे कॉलर को पता चलता है कि हम उस बिंदु पर पहुंच गए हैं जहां हम हमारे वादे को नहीं रख सकते हैं।

क्या आप चाहते हैं बुनियादी त्रुटि हैंडलिंग है ...

function someCode(){ 
     $pdostmt = $this->prepare($this->sql); 
     if($pdostmt->execute($this->bind) !== false) { 
      if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) 
       return $pdostmt->fetchAll($this->fetchOption); 
      elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) 
       return $pdostmt->rowCount(); 
     } else { 
      return false; 
     } 
} 

while (someCode() === false) { 
    /* Call someCode() until you get what you want */ 
} 
+0

तो आखिरकार PHP 5.5 में क्या उद्देश्य है? मैं हमेशा पकड़ने के बाद यह सुनिश्चित करने के लिए वहां था कि यह निष्पादन जारी रखता है और स्क्रिप्ट को रोक नहीं देता है। – MCHam

+0

@MCHam 'आखिरकार' का उद्देश्य यह सुनिश्चित करना है कि एक कोडब्लॉक ** ** के बावजूद एक अपवाद को 'कोशिश' ब्लॉक के अंदर फेंक दिया गया है या नहीं और यह 'कैच' ब्लॉक के अंदर संभाला गया है या नहीं। ** केवल अनन्य बहिष्करण हैं FATAL ** – Sherif

+0

PHP 5.5+ में यदि आपके पास अपने प्रयास ब्लॉक में रिटर्न स्टेटमेंट है, तो यह वास्तव में वास्तव में लौटने से पहले अंततः ब्लॉक निष्पादित करेगा (जबकि यदि आपके पास पकड़ ब्लॉक के बाद कोड है, तो भीतर से लौट रहा है कोशिश ब्लॉक उस कोड को निष्पादित नहीं करेगा)। आखिर में एक ब्लॉक ब्लॉक गारंटी देता है कि आपका कोड कॉल किया जाएगा चाहे कोई अपवाद संभाला गया हो या नहीं, और इस पर ध्यान दिए बिना कि आपका प्रयास कोड वापस आता है या नहीं। – Russ

0

आप, अंत में कोशिश पकड़ने का हिस्सा उपयोग करने के लिए यदि आप निष्पादन में एक अपवाद नहीं मिलेगा सक्षम हो सकता है समय समाप्त हो गया के लिए कहते हैं कि सुविधा देता है। सब से

try { 
    // some crashing code 
} catch (Exception $e) { 
    //some catch code 
} finally { 
    //code that will run anyways. 
} 
+0

अंततः PHP 5.5 से एक सुविधा नहीं है (इसलिए अभ्यास में अभी भी कोई नहीं है)? – Smar

+0

... और अपवाद को फेंकने पर सटीक बिंदु से * फिर से शुरू नहीं होगा। यह सिर्फ कथन का एक हार्ड कोड कोड सेट करेगा। –

+0

दोनों टिप्पणियों के लिए हाँ। – jaudette

3

उपयोग php 4/5 register_shutdown_function।

यहां डॉक्टर: http://php.net/manual/en/function.register-shutdown-function.php

+0

धन्यवाद कि मैं बस यही देख रहा था! इसे कहीं और नहीं मिला। मैं एक वैश्विक "आखिरकार" की तलाश में था। UNCAUGHT अपवाद के बाद निष्पादित करने के लिए कुछ। धन्यवाद। – adjenks

3

मुझे लगता है कि आप समारोह में यह फेंक दिया जा रहा है में अपवाद प्रबंधित नहीं कर रहा हूँ। यदि आप फिर से शुरू करना चाहते हैं कि आपका अपवाद कहाँ फेंक दिया गया है तो आपको अपवाद को संभालने की आवश्यकता है। कुछ भी खराब कोडिंग है जिसके परिणामस्वरूप आप या परियोजना पर काम करने वाले किसी और के लिए भ्रम पैदा होता है। हम अपवाद को पेड़ पर जाने देते हैं क्योंकि हम उन्हें स्कोप मुद्दों के कारण स्वयं कार्य में संभाल नहीं सकते हैं।

आपके उदाहरण के अनुसार जो मैं विस्तार करूंगा। आप कहते हैं कि ऑपरेशन जारी नहीं रह सकता क्योंकि कनेक्शन नहीं हो सकता है।हकीकत में हम फ़ंक्शन को फिर से प्रयास नहीं करना चाहते हैं क्योंकि हम अनिवार्य रूप से कनेक्शन की कोशिश करने का एक लटका बिंदु बनायेंगे, इसलिए हम पेड़ को ऊपर पकड़ने वाले कैच ब्लॉक का उपयोग करते हैं जहां हम उपयोगकर्ता को सूचित कर सकते हैं और उन्हें यह तय कर सकते हैं कि हम क्या करना चाहते हैं । ऐसा करने में हम डेटा को बचाने के लिए सही स्थानों पर कैच ब्लॉक का उपयोग कर सकते हैं ताकि हम डेटा को पुनर्स्थापित कर सकें और बाद में इसे निष्पादित कर सकें। हकीकत में हम प्रयास ब्लॉक से पहले एक बिंदु पर हवा-अप करना चाहते हैं।

यह आपको एक स्पष्ट निष्पादन पथ प्रदान करेगा। कभी-कभी आपको किसी फ़ंक्शन/विधि पर पुनर्विचार करना पड़ता है ताकि यह एक चीज और एक चीज़ सही तरीके से करे।

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

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

function someCode() { 
    $pdostmt = $this->prepare($this->sql); 

    while($status == false) { 
     try { 
      $status = $pdostmt->execute($this->bind) 

     } catch (PDOException $e) { 
      if($e->getMessage("What ever the error message is") { 
       //Fix it here 
      } else { 
       throw $e; 
      } 
     } 
    } 
    //Do other stuff 
    return $data; //or true/false 
} 
+0

"यदि आप फिर से शुरू करना चाहते हैं कि आपका अपवाद कहाँ फेंक दिया गया है तो आपको अपवाद को संभालने की आवश्यकता है।" - किसी भी व्यक्ति जो टीएल चाहता है; डॉ - यह महत्वपूर्ण हिस्सा है और इसके बारे में जाने का 100% सही तरीका है। –