8

मैं हाल ही में कुछ कोड में आया था कि किसी भी PHP त्रुटियों को सामान्यीकृत अपवाद में बदलने के लिए कस्टम त्रुटि हैंडलर का उपयोग किया गया था। एक कस्टम अपवाद हैंडलर को भी परिभाषित किया गया था कि अगर यह एक विशेष त्रुटि कोड सीमा के भीतर था तो अपवाद लॉग करेगा। उदाहरण:अपवादों में त्रुटियों को परिवर्तित करना: डिज़ाइन दोष?

try 
{ 
    do_something(); 
} 
catch (AppException $exception) 
{ 
} 

कौन सा अर्थ है वास्तविक प्रोग्रामिंग त्रुटियों और "असाधारण" व्यवहार के बीच कोई फर्क नहीं है:

class AppException extends Exception 
{ 

} 

function error_handler($errno, $errstr, $errfile, $errline) 
{ 
    throw new AppException($errstr, $errno); 
} 

function exception_handler($exception) 
{ 
    $min = ...; 
    $max = ...; 

    if ($exception->getCode() >= $min && $exception->getCode() <= $max) 
    { 
     // log exception 
    } 
} 

set_error_handler('error_handler'); 
set_exception_handler('exception_handler'); 

$a[1]; // throws exception 

समस्या यह है कि मैं जैसी चीजों को देखा है।

... 

function my_function($param1, $param2) 
{ 
    // do something great 
} 

try 
{ 
    my_function('only_one_param'); 
} 
catch (AppException $exception) 
{ 
} 

कौन सा मुश्किल होता त्रुटियों और आवेदन के इंटरफ़ेस के डिजाइन समाप्त होता है: आगे खुदाई करने पर, मैंने कोड के कुछ हिस्सों कि विचार के आसपास जैसे कि PHP त्रुटियों का प्रतिनिधित्व किया "असाधारण" व्यवहार डिजाइन किए गए थे भर में आया था।

इस तरह की त्रुटियों को संभालने पर आपकी राय क्या है? क्या यह PHP की मूल त्रुटियों को अपवादों में बदलने लायक है? उपरोक्त स्थितियों में आप क्या करते हैं जहां इस विचार के आसपास कोडबेस बनाया गया है?

उत्तर

15

व्यक्तिगत रूप से, मैं यह हर समय करता हूं। फर्क सिर्फ इतना है कि मेरे error_handler समारोह में, मैं यह जांच लें कि त्रुटि एक E_NOTICE पहले है, और केवल फेंक अगर यह (मैं नोटिस लोग इन वैसे भी) नहीं है ...

मैं कुछ करने के लिए AppException बदल जाएगा है जो ErrorException बढ़ाता है ... कुछ ऐसा: PhpRuntimeErrorException extends ErrorException जो आप केवल PHP त्रुटियों के लिए उपयोग करते हैं ... कारण यह है कि यह अधिक पठनीय है (यह कहना आसान है कि PhpRuntimeErrorException को यह पता लगाने में आसान है कि इसे कहां फेंक दिया गया है)। अन्य कारण यह है कि ErrorException पैदा लाइन/फ़ाइल/etc जानकारी है, जहां यह कहीं और संग्रहीत नहीं किया जाएगा (के बाद से पश्व-अनुरेखन throw लाइन से शुरू होता है) ...

तो स्टोर करेगा है, तो आप "कोशिश कर सकते हैं "इस तरह कोड:

try { 
    $f = fopen('foo.bar', 'r'); 
    $ret = ''; 
    while ($data = fread($f)) { 
     $ret .= process($data); 
    } 
    fclose($f); 
    return ''; 
} catch (PHPRuntimeErrorException $e) { 
    throw new RuntimeException('Could not open file'); 
} catch (ProcessException $e) { 
    fclose($f); 
    throw new RuntimeException('Could not process data'); 
} 
return $ret; 

मैं अपना डिफ़ॉल्ट अपवाद हैंडलर 500 सर्वर त्रुटि पृष्ठ उत्पन्न करता हूं। ऐसा इसलिए है क्योंकि किसी भी अपवाद पकड़ा जाना चाहिए है, और अगर वे नहीं थे, यह वास्तव में एक सर्वर त्रुटि है ...

बस मेरे अनुभव और राय ...

+0

हां कि सब अच्छा लगता है, एक PHP त्रुटि विशिष्ट अपवाद को AppException बदलते क्या दिमाग में पहले आया था है। हालांकि मुझे आश्चर्य है कि इस समाधान के बीच अंतर क्या है और वास्तविक त्रुटियों के अपवादों का उपयोग किये बिना कस्टम त्रुटि हैंडलर में 500 सर्वर त्रुटि उत्पन्न करना। इसके अलावा, क्या ऐसा करने के लिए कोई ओवरहेड है? –

+0

ठीक है, यह उपरि के बारे में नहीं है। मैं केवल अनचाहे अपवादों के लिए 500 त्रुटि पृष्ठ उत्पन्न करता हूं। अक्सर कई बार होते हैं जब मैं PHP त्रुटियों को पकड़ता हूं और प्रसंस्करण जारी रखता हूं। उदाहरण के लिए, यदि डोम डॉक्यूमेंट एक एक्सएमएल स्ट्रिंग को पार्स नहीं कर सकता है तो चेतावनी उठाएगी। इसलिए मैं उस त्रुटि को कैप्चर करता हूं, और फ़ाइल का प्रयास करने और पुनः प्रयास करने के लिए इसका उपयोग करता हूं 'try {$ dom-> loadXml ($ xml); } पकड़ो (PhpRuntimeErrorException $ ई) {$ xml = XmlCleaner :: साफ़ ($ xml); $ Dom-> loadXml ($ एक्सएमएल); } 'मैं' एक्सएमएल क्लेनर 'नहीं चलाऊंगा, क्योंकि यह वास्तव में काफी महंगा है। तो मैंने PHP त्रुटि को मुझे यह कहने के लिए कहा कि ... – ircmaxell

4

पीएचपी समुदाय में इस बारे में कुछ बहस हुई है । मेरा मानना ​​है कि सामान्य सोच यह है कि आंतरिक PHP कार्यों द्वारा त्रुटियों को फेंक दिया जाता है, और कोडिंग समस्याएं हैं जिन्हें आपको वास्तव में ठीक करने की आवश्यकता है; जबकि अपवाद आपके एप्लिकेशन कोड द्वारा फेंकने वाली चीजें हैं जिन्हें आपको केवल 'हैंडल' करने की आवश्यकता हो सकती है।

हालांकि कुछ नए एसपीएल एक्सटेंशन (जो अधिक ऑब्जेक्ट उन्मुख होते हैं) उन चीजों के लिए अपवादों का उपयोग करते हैं जो पहले त्रुटियों को फेंक चुके थे, इसलिए कुछ ग्रे क्षेत्र है।

एक PHP कोर क्लास त्रुटि अपवाद - http://www.php.net/manual/en/class.errorexception.php भी है जो आपके कोड उदाहरण से उपयोग करने में थोड़ा आसान लग रहा है, यदि यह एक मार्ग है जिसे आप नीचे जाना चाहते हैं।

+0

यह मेरा विचार भी था ... मुझे लगता है कि भ्रम इस तथ्य से आता है कि कई त्रुटि हैंडलिंग तंत्र और कोई वास्तविक मानक नहीं हैं। मैंने ErrorException क्लास पर एक नज़र डाली और यह एक अच्छा पहला कदम जैसा दिखता है। –

+0

ठीक है, कुछ के लिए, हाँ। जैसे कि आप 'fopen ($ foo)' कहते हैं, आपको एक त्रुटि मिलनी चाहिए क्योंकि आप दूसरा param याद कर रहे हैं। लेकिन अगर आप 'parse_url ($ url)' कहते हैं, और '$ url' वास्तव में विकृत यूआरएल है, तो आपको वहां एक चेतावनी भी मिल जाएगी। तो कुछ मामलों में, हाँ वे कोडिंग समस्याएं हैं। लेकिन वहां बड़ी संख्या में "रनटाइम" समस्याएं हैं जिनके पास कोडिंग के साथ कुछ भी नहीं है ... तो यह वास्तव में सिर्फ एक बात है कि आप अपनी त्रुटियों को कैसे संभालना चाहते हैं (मुझे अपने अपवाद पसंद हैं। अगर आप नहीं करते हैं, तो यह ठीक है जब तक आप लगातार और विधिवत होते हैं, तब तक यह वास्तव में अंत में मायने रखता है) ... – ircmaxell

+0

निश्चित रूप से, मुझे लगता है कि यह एक बहुत अच्छा मामला है, मैं कड़ाई से प्रोग्रामिंग त्रुटियों के बारे में सोच रहा था, लेकिन इससे अधिक समझ में आता है। –

1

मैं अपवादों के नोटिस सहित सबकुछ बदलता हूं। अपवादों को सामान्य रूप से जारी रखने की अनुमति देने का कोई कारण नहीं है। अपरिभाषित चर या ऑफ़सेट? ये एक समस्या है।

https://github.com/KyleWolfe/PHPErrorNet

+0

>> "अपरिभाषित चर या ऑफसेट? यह एक समस्या है।" उहम्म ... क्या होगा यदि ऑफसेट पर डेटा वैकल्पिक है? – TheRealChx101

+2

http://php.net/manual/en/function.isset.php – kwolfe

+0

हा। जांच करने के लिए चर के एक टन होने पर मुझे परेशान नहीं है। मैं '$ foo = $ _GET ['foo'] करता हूं; 'फिर पृष्ठ में कहीं' अगर (जारी ($ foo))'। यह चेतावनियां उत्पन्न करता है लेकिन कौन परवाह करता है। :) – TheRealChx101

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