2012-05-09 15 views
33

पर स्क्रिप्ट निष्पादन रोकें क्या वैश्विक स्तर पर नोटिस/चेतावनी पर PHP रोक निष्पादन संभव है?नोटिस/चेतावनी

हम कई साइटों के साथ एक विकास सर्वर चलाते हैं, लेकिन इन डेवलपर्स को इन चेतावनियों/नोटिस (या कम से कम उनके साथ मदद मांगना) को अनदेखा करने और आगे बढ़ने के बजाय मजबूर करना चाहते हैं।

उत्तर

47

हां, यह संभव है। यह सवाल PHP में त्रुटियों को संभालने के तरीके के बारे में अधिक सामान्य मुद्दे से बात करता है। PHP त्रुटियों के लिए हैंडलिंग को अनुकूलित करने के लिए आपको set_error_handlerdocs का उपयोग करके एक कस्टम त्रुटि हैंडलर को परिभाषित और पंजीकृत करना चाहिए।

IMHO किसी भी PHP त्रुटि पर अपवाद फेंकना और कार्यक्रम प्रवाह को नियंत्रित करने के लिए प्रयास/पकड़ ब्लॉक का उपयोग करना सबसे अच्छा है, लेकिन इस बिंदु पर राय अलग-अलग होती है।

ओपी के घोषित लक्ष्य आप की तरह कुछ कर सकता करने के लिए:

function errHandle($errNo, $errStr, $errFile, $errLine) { 
    $msg = "$errStr in $errFile on line $errLine"; 
    if ($errNo == E_NOTICE || $errNo == E_WARNING) { 
     throw new ErrorException($msg, $errNo); 
    } else { 
     echo $msg; 
    } 
} 

set_error_handler('errHandle'); 

ऊपर कोड एक ErrorException किसी भी समय एक E_NOTICE या E_WARNING फेंक होगा उठाया है, प्रभावी रूप से स्क्रिप्ट निर्गम (समाप्त करने जैसे अपवाद नहीं है पकड़े गए)। पीएचपी त्रुटियों पर फेंकने अपवाद सबसे अच्छा एक समानांतर अपवाद संचालन रणनीति (set_exception_handler) शान से उत्पादन वातावरण में समाप्त करने के लिए के साथ संयुक्त है।

ध्यान दें कि ऊपर के उदाहरण @ त्रुटि दमन ऑपरेटर अनुपालन नहीं करेंगे। यदि यह आप के लिए महत्वपूर्ण है, बस के रूप में यहां प्रदर्शन किया error_reporting() समारोह के साथ एक चेक जोड़ें:

function errHandle($errNo, $errStr, $errFile, $errLine) { 
    if (error_reporting() == 0) { 
     // @ suppression used, don't worry about it 
     return; 
    } 
    // handle error here 
} 
+0

और त्रुटि हैंडलर को 'auto_prepend_file' सेटिंग के माध्यम से परिभाषित और पंजीकृत किया जा सकता है। – goat

+0

अच्छी चीजें, auto_prepend_file यह है :-) .. चलो देखते हैं कि कैसे Magento इस अपवाद हैंडलिंग के इसटॉप को पसंद करता है। – Michael

+0

इसके लायक होने के लिए, मैं दृढ़ता से 'auto_prepend_file' के उपयोग को हतोत्साहित करता हूं। – rdlowrey

-4

आप अपने सर्वर के PHP विन्यास फाइल में E_ALL को error_reporting चालू कर सकते हैं।

PHP 5 में एक नया त्रुटि स्तर E_STRICT उपलब्ध है। चूंकि E_STRICT को E_ALL में शामिल नहीं किया गया है, इसलिए आपको इस तरह के त्रुटि स्तर को स्पष्ट रूप से सक्षम करना होगा। विकास के दौरान E_STRICT को सक्षम करने के कुछ फायदे हैं। सख्त संदेश आप कोडिंग के नवीनतम और सबसे बड़ी सुझाव विधि का उपयोग करने में मदद मिलेगी, उदाहरण के लिए आप पदावनत कार्यों का उपयोग कर के बारे में चेतावनी।

संदर्भ: PHP Configuration Manual

निम्न सेटिंग्स आप उत्पादन के लिए सभी त्रुटियों को एक स्क्रिप्ट में मार्गदर्शन। कृपया ध्यान दें कि इन अपने सभी स्क्रिप्ट फ़ाइलें के शुरू में शामिल किए जाने की आवश्यकता होगी।

<?php 

// Turn off all error reporting 
error_reporting(0); 

// Report simple running errors 
error_reporting(E_ERROR | E_WARNING | E_PARSE); 

// Reporting E_NOTICE can be good too (to report uninitialized 
// variables or catch variable name misspellings ...) 
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); 

// Report all errors except E_NOTICE 
// This is the default value set in php.ini 
error_reporting(E_ALL^E_NOTICE); 

// Report all PHP errors (see changelog) 
error_reporting(E_ALL); 

// Report all PHP errors 
error_reporting(-1); 

// Same as error_reporting(E_ALL); 
ini_set('error_reporting', E_ALL); 

?> 
+1

आपके उत्तर में प्रश्न के "निष्पादन रोकें" भाग गुम है। त्रुटि रिपोर्टिंग सेट करने से केवल आउटपुट प्रभावित हो जाएगा (या तो स्क्रीन पर या लॉग में), लेकिन केवल त्रुटियां या मोटाई स्क्रिप्ट को रोक देंगे - चेतावनियां और नोटिस नहीं होंगे। – Sven

6

आप वैश्विक रूप से इसे अपने php.ini file­Docs में कॉन्फ़िगर कर सकते हैं।

auto_prepend_file "/full/path/to/a/prepend-file.php" 

कर कि तुम अंदर वैश्विक php.ini फ़ाइल यह सुनिश्चित करेंगे कि आगे जोड़ते फाइल के अंदर कोड होगा:

आप एक फ़ाइल है कि auto_prepend_file directive­Docs के साथ सभी पीएचपी प्रक्रियाओं द्वारा शामिल किए जाने का उल्लेख करके ऐसा करते हैं हमेशा exectued। आप यह तो उपयोग कर सकते हैं एक वैश्विक त्रुटि हैंडलर कि turn all errors into exceptions­Docs होगा रजिस्टर करने के लिए:

<?php 
function exception_error_handler($errno, $errstr, $errfile, $errline) { 
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 
} 
set_error_handler("exception_error_handler"); 

इस छोटे स्क्रिप्ट एक ErrorException में सभी त्रुटियों/चेतावनी/नोटिस आदि हो जाएगा।

इसे error_reporting ini directive­Docs के साथ संयोजित करें, मान आपकी php.ini फ़ाइल में वर्णित हैं।

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

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

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

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

+1

रिकॉर्ड के लिए, मैं 'auto_prepend_file' के उपयोग का समर्थन नहीं करता हूं। मुझे लगता है कि कोड क्या हो रहा है इसके बारे में स्पष्ट होना चाहिए। मैं जादू व्यवहार में परिणामस्वरूप php.ini निर्देश नहीं चाहता हूं जिसे मैं वास्तविक स्रोत कोड में नहीं देख सकता। IMHO यह एक सरल 'आवश्यकता' कॉल करने के लिए * अधिक * बेहतर है। जब आप कोड के टुकड़े को देखते हैं तो आप एक महीने का क्या होता है और आप अपनी सैनिटी खो देते हैं क्योंकि इसका कोई मतलब नहीं है कि कुछ क्यों हो रहा है? क्या होता है यदि कोई नया डेवलपर टीम में शामिल हो जाता है? उन्हें पता नहीं होगा कि एक php.ini निर्देश स्वचालित रूप से कोड सहित है। – rdlowrey

+0

आगे, क्या होगा यदि प्रत्येक PHP निष्पादन को उसी तरह त्रुटियों को संभाल नहीं लेना चाहिए? 'auto_prepend_file' और' auto_append_file' आपको अनिवार्य रूप से विशिष्ट व्यवहार में लॉक कर देता है और मैं इसे PHP के "खराब हिस्सों" में से एक के रूप में देखता हूं। बस मेरे दो सेंट :) – rdlowrey

+0

@rdlowrey: 'auto_prepend_file' में कमजोरियां हैं, लेकिन शुरुआत करने वालों के लिए जाने देना आसान है। मैं व्यक्तिगत रूप से शेल स्क्रिप्ट के साथ लॉग पर अधिक केंद्रीय लॉगिंग और हुकिंग से प्यार करता हूं, उदाहरण के लिए डेस्कटॉप पर त्रुटियों को सूचित करके: https://github.com/ktomk/Miscellaneous/tree/master/notify-phperrors – hakre

5

पीएचपी 5.3.0 के रूप में:

set_error_handler(
    function(int $nSeverity, string $strMessage, string $strFilePath, int $nLineNumber){ 
     if(error_reporting()!==0) // Not error suppression operator @ 
      throw new \ErrorException($strMessage, /*nExceptionCode*/ 0, $nSeverity, $strFilePath, $nLineNumber); 
    }, 
    /*E_ALL*/ -1 
); 
3

आप एक विकास के वातावरण में हैं, तो आप मॉड्यूल Xdebug स्थापित करने पर विचार करने और अपने पीएचपी INI फ़ाइलों से कहीं xdebug.halt_level=E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE सेट कर सकते हैं। डेवलपर xdebug.halt_level रीसेट कर सकता है, लेकिन हमारे पास set_error_handler पर आधारित उत्तर के साथ एक ही समस्या है, क्योंकि हम हैंडलर को इसके मूल मूल्य में पुनर्स्थापित कर सकते हैं।

+0

मैं व्यक्तिगत रूप से इस दृष्टिकोण को पसंद करता हूं। हमारे लिए, स्केलेबिलिटी के मामले में यह दृष्टिकोण सबसे अच्छा है। गैर-उत्पादन वातावरण (विकास, परीक्षण, चरण, आदि) सभी एकल मशीनों/उदाहरणों पर चलते हैं। उत्पादन कई में संतुलित है। ऑटो/प्रीलोडेड फाइलें रखने का विचार केवल समस्याओं के लिए एक अतिरिक्त क्षेत्र प्रदान करता है। इस दृष्टिकोण के साथ, सभी वातावरण समान हैं, सिवाय इसके कि गैर-उत्पाद अनिवार्य रूप से कुछ भी बंद हो जाता है, जो उत्पादन पर समाप्त होने वाले विनाश को समाप्त करता है। – conrad10781

0

अन्य समाधान एक कस्टम त्रुटि हैंडलर जो डिफ़ॉल्ट त्रुटि लॉगिंग तंत्र को ओवरराइड करता है को लागू। इसका अर्थ यह है कि जब हम एक कस्टम त्रुटि हैंडलर सेट करते हैं, तो सूचना/चेतावनी डिफ़ॉल्ट रूप से अब मुद्रित नहीं होती है, इसलिए हम केवल "नोटिस/चेतावनी पर स्क्रिप्ट निष्पादन को रोकें" से अधिक बदलते हैं।

हालांकि, मुझे अभी भी संदेश प्रिंट करने का एक तरीका चाहिए - मेरे मामले में PHP सीएलआई में - क्योंकि आउटपुट को फिर किसी अन्य प्रोग्राम द्वारा पार्स किया जाता है। इसलिए मैं में में संदेश मुद्रित नहीं करना चाहता था, लेकिन PHP की तुलना में ठीक उसी तरह से करता है। मैं सिर्फ सही होने के बाद एक नोटिस/चेतावनी मुद्रित किया गया था != 0 की एक निकास कोड के साथ रोक पीएचपी CLI प्रक्रिया चाहता था , और बाकी कुछ भी नहीं बदलते।

दुर्भाग्यवश, को बिना किसी त्रुटि के 0 स्क्रिप्ट को को संभाले बिना स्क्रिप्ट से बाहर निकलने का डिफ़ॉल्ट तरीका प्रतीत नहीं होता है। तो मुझे PHP में डिफ़ॉल्ट त्रुटि हैंडलर (जिसे सी में कार्यान्वित किया गया है) को फिर से लागू करने की आवश्यकता है।

इसके लिए, मैंने PHP के स्रोत कोड में डिफ़ॉल्ट त्रुटि मुद्रण तंत्र को देखा और निम्न त्रुटि हैंडलर प्राप्त करने के लिए प्रासंगिक टुकड़े को सी से PHP तक पोर्ट किया, जो आपको कुछ समान की आवश्यकता होने पर आपके साथ साझा करना चाहता है:

set_error_handler(
    function($errNo, $errStr, $errFile, $errLine) { 
     $error_type_str = 'Error'; 
     // Source of the switch logic: default error handler in PHP's main.c 
     switch ($errNo) { 
      case E_ERROR: 
      case E_CORE_ERROR: 
      case E_COMPILE_ERROR: 
      case E_USER_ERROR: 
       $error_type_str = "Fatal error"; 
       break; 
      case E_RECOVERABLE_ERROR: 
       $error_type_str = "Recoverable fatal error"; 
       break; 
      case E_WARNING: 
      case E_CORE_WARNING: 
      case E_COMPILE_WARNING: 
      case E_USER_WARNING: 
       $error_type_str = "Warning"; 
       break; 
      case E_PARSE: 
       $error_type_str = "Parse error"; 
       break; 
      case E_NOTICE: 
      case E_USER_NOTICE: 
       $error_type_str = "Notice"; 
       break; 
      case E_STRICT: 
       $error_type_str = "Strict Standards"; 
       break; 
      case E_DEPRECATED: 
      case E_USER_DEPRECATED: 
       $error_type_str = "Deprecated"; 
       break; 
      default: 
       $error_type_str = "Unknown error"; 
       break; 
     } 
     fwrite(STDERR, "PHP $error_type_str: $errStr in $errFile on line $errLine\n"); 
     exit(1); 
    }, 
    E_ALL 
); 

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

  • कोई संबंधित समस्या नहीं^_^