क्या मुझे अपने PHP कोड में मुखर का उपयोग करना चाहिए?


87

एक सहकर्मी ने हमारे पुस्तकालयों के भीतर उन जगहों पर कुछ समय के लिए मुखर कमान जोड़ दी है जहां मैंने एक बयान का उपयोग किया होगा और एक अपवाद को फेंक दिया होगा। (मैंने इससे पहले कभी मुखर होने के बारे में नहीं सुना था।) यहां एक उदाहरण दिया गया है कि उन्होंने इसका इस्तेमाल कैसे किया:

assert('isset($this->records); /* Records must be set before this is called. */');

मैंने कर दिया होता:

if (!isset($this->records)) {
    throw new Exception('Records must be set before this is called');
}

मुखर पर PHP डॉक्स पढ़ने से , ऐसा लगता है कि यह अनुशंसा की जाती है कि आप सुनिश्चित करें कि मुखर सक्रिय है और मुखर का उपयोग करने से पहले एक हैंडलर जोड़ें। मुझे ऐसा कोई स्थान नहीं मिला जहाँ उसने ऐसा किया हो।

तो, मेरा प्रश्न यह है कि क्या ऊपर दिए गए एक अच्छे विचार का उपयोग किया जा रहा है और क्या मुझे इफ और अपवादों के बजाय इसका अधिक बार उपयोग करना चाहिए?

एक और ध्यान दें, हम इन पुस्तकालयों का उपयोग विभिन्न परियोजनाओं और सर्वरों पर करने की योजना बना रहे हैं, जिनमें ऐसी परियोजनाएँ भी शामिल हैं जिनका हम हिस्सा भी नहीं हो सकते हैं (पुस्तकालय खुला स्रोत हैं)। क्या इस दावे का उपयोग करने में कोई फर्क पड़ता है?


क्या यह वास्तव में है 'isset(कोड लाइन के साथ assert)? सिर्फ isset(एकल उद्धरण के बिना ') नहीं?
पीटर मोर्टेंसन

जवाबों:


79

अंगूठे का नियम जो अधिकांश भाषाओं में लागू होता है (सभी जो मुझे अस्पष्ट रूप से पता है) यह है assertकि ए का उपयोग यह दावा करने के लिए किया जाता है कि एक शर्त हमेशा सच होती है जबकि एक ifउचित है यदि यह बोधगम्य है कि यह कभी-कभी विफल हो जाएगी।

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

assertविरोध के रूप में उपयोग करने का लाभ यह ifहै कि assertआम तौर पर उत्पादन कोड में बंद किया जा सकता है इस प्रकार ओवरहेड को कम किया जा सकता है। इस तरह की परिस्थितियां जो सबसे अच्छी तरह से संभाली जाती हैं if, उत्पादन प्रणाली में रनटाइम के दौरान हो सकती हैं और इसलिए उन्हें बंद नहीं करने से कुछ भी नहीं खोता है।


4
इसे जोड़ने के लिए, आप अपने उत्पादन कोड में अभिक्रियाओं को निष्क्रिय नहीं करना चाह सकते हैं, क्योंकि वे यह सुनिश्चित करने में मदद करते हैं कि "ऐसा कभी नहीं होना चाहिए" स्थितियाँ इस तरह बनी रहें। बेहतर हो सकता है कि आपके एप्लिकेशन को जोर देने से रोकने के बजाय अपने उपयोगकर्ताओं को निष्पादन पथ के साथ जाने दें जो मौजूद नहीं होना चाहिए।
derekerdmann

2
@ डेरेकडमैन: सच। कुछ अनुमानों के लिए उन्हें (उत्पादन में) लॉग इन करना या चेतावनी (विकास के माहौल में) मुद्रित करना पर्याप्त हो सकता है। लेकिन चूंकि बार-बार जोर लगाने से सुरक्षा प्रासंगिक कोड की सुरक्षा होती है, इसलिए आप सक्षम भी हो सकते हैं assert_options(ASSERT_BAIL)। यह मैनुअल से भी तेज़ है अगर / फिर भी वर्कअराउंड को फेंक दें।
मारियो

4
@derekerdmann मैं इस पर असहमत होगा (asp का उपयोग करने के संदर्भ में) php में। यह एक बड़ा भेद्यता अंतराल है, क्योंकि मुखर () सभी स्ट्रिंग तर्कों को PHP कोड के रूप में मानता है, इस प्रकार यह (सैद्धांतिक रूप से) मनमाना कोड को इंजेक्ट और चलाना संभव है। IMHO, अभिकथन उत्पादन पर बंद कर दिया जाना चाहिए
विटालि लेबेडेव

2
@VitaliyLebedev यदि आप इंजेक्शन के लिए अतिसंवेदनशील नहीं होना चाहते हैं तो स्ट्रिंग को पास न करें।
डेमोन स्नाइडर

9
पार्टी के लिए देर से लेकिन PHP.net बताता है: "अभिक्रिया का उपयोग केवल डीबगिंग सुविधा के रूप में किया जाना चाहिए।"
कोएन।

25

"सत्ता टिप्पणियों" के रूप में जोर देते हैं। इसके बजाय एक टिप्पणी की तरह:

// Note to developers: the parameter "a" should always be a number!!!

उपयोग:

assert('is_numeric(a) /* The parameter "a" should always be a number. */');

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

इस तरह देखा, अगर (त्रुटि) ... और अपवादों की तुलना में दावे पूरी तरह से अलग अवधारणा हैं, और वे सह-अस्तित्व में हो सकते हैं।

हां, आपको अपने कोड पर टिप्पणी करनी चाहिए, और हां, जब भी संभव हो, आपको "पावर कमेंट्स" (जोर) का उपयोग करना चाहिए।


क्या होगा अगर परीक्षण करते समय आप हमेशा परख करने के लिए अच्छी स्थिति से गुजरते हैं, लेकिन उत्पादन में अगर मुखर हो जाता है - तो कुछ उपयोगकर्ता एक और शर्त से गुजरते हैं जिसके बारे में आपने परीक्षण के दौरान नहीं सोचा था? या अन्यथा आपको हमेशा मुखर रहने की आवश्यकता है, लेकिन क्या यह आपके स्वयं के चेक लिखने के समान नहीं है?
डेरियस .V

तब आपका प्रोग्राम फेल हो जाएगा। यदि कथन और आपकी भाषा और विकास के वातावरण की त्रुटियों से निपटने में त्रुटि के साथ इसे ठीक करें। मुखर समस्याओं को उजागर कर सकते हैं, समस्याओं को ठीक करने के बेहतर तरीके हैं।
डेववेल्ले

ध्यान दें कि PHP 7.2 के रूप में मूल्यांकन के लिए मुखर में एक स्ट्रिंग पारित किया गया है। दुखद, क्योंकि यह काफी काम लग रहा था।
जेनी थुनिसन

16

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

मुखर उपयोगी है, क्योंकि इसे सक्षम और अक्षम किया जा सकता है। यदि ऐसा कोई दावा हैंडलर परिभाषित नहीं किया जाता है, तो यह प्रदर्शन को नहीं मिटाता है। आपके सहयोगी के पास एक नहीं है, और आपको कुछ कोड तैयार करने चाहिए, जो अस्थायी रूप से विकास के माहौल में सक्षम बनाता है (यदि E_NOTICE / E_WARNINGs चालू हैं, तो मुखर हैंडलर होना चाहिए)। मैं कभी-कभी इसका उपयोग करता हूं जहां मेरा कोड मिश्रित परिवर्तनीय प्रकारों को पेट नहीं कर सकता है - मैं आमतौर पर कमजोर टाइप किए गए PHP में सख्त टाइपिंग में संलग्न नहीं होता हूं, लेकिन यादृच्छिक उपयोग के मामले हैं:

 function xyz($a, $b) {
     assert(is_string($a));
     assert(is_array($b));

उदाहरण के लिए जो टाइप स्पेसर की कमी की भरपाई करेगा string $a, array $b। PHP5.4 उनका समर्थन करेगा, लेकिन जाँच नहीं।


"Php 5.4 के पास क्या होगा लेकिन उनकी जांच नहीं होगी" मतलब है?
क्ज़ेकई

1
PHP 5.4 में मुखरता है, समर्थन करता है और जाँच करता है।
डेवलेले

7

अभिकर्मक सामान्य प्रवाह नियंत्रण जैसे ifया अपवादों का विकल्प नहीं है, क्योंकि इसका उपयोग केवल विकास के दौरान डीबगिंग के लिए किया जाना है।


6

PHP में assert से संबंधित एक महत्वपूर्ण नोट 7. पहले की तुलना में अन्य भाषाओं में एक assert निर्माण के साथ, PHP पूरी तरह से मुखर बयान नहीं फेंकती है - यह इसे एक फ़ंक्शन के रूप में मानता है (एक अभिकथन द्वारा कहे गए फ़ंक्शन में एक debug_backtrace)। बंद कर देता है इंजन में कुछ भी नहीं करने के लिए सिर्फ समारोह hotwire लगता है। ध्यान दें कि PHP 7 को 1 (ऑन) या -1 (ऑफ) के अधिक सामान्य मूल्यों के बजाय zend.assertions को 0 पर सेट करके इस व्यवहार का अनुकरण किया जा सकता है।

समस्या यह उठती है कि मुखर कोई तर्क लेगा - लेकिन यदि तर्क एक स्ट्रिंग नहीं है, तो मुखर को अभिव्यक्ति के परिणाम मिलते हैं कि क्या मुखर चालू या बंद है। आप इसे निम्न कोड ब्लॉक से सत्यापित कर सकते हैं।

<?php
  function foo($a) { 
    echo $a . "\n"; 
    return TRUE;
  }
  assert_options(ASSERT_ACTIVE, FALSE);

  assert( foo('You will see me.'));
  assert('foo(\'You will not see me.\')');

  assert_options(ASSERT_ACTIVE, TRUE);

  assert( foo('Now you will see'));
  assert('foo(\'both of us.\')');

मुखर के इरादे को देखते हुए यह एक बग है, और एक लंबे समय से यह भाषा में है क्योंकि मुखर को PHP 4 में वापस पेश किया गया था।

मुखरता के लिए उत्तीर्ण स्ट्रिंग्स को सभी प्रदर्शन निहितार्थों और खतरों के साथ विकसित किया जाता है, लेकिन यह मुखर बयानों को प्राप्त करने का एकमात्र तरीका है जिस तरह से उन्हें PHP में काम करना चाहिए (यह व्यवहार PHP 7.2 में चित्रित किया गया है)।

EDIT: PHP 7 और 7.2 में परिवर्तन पर ध्यान देने के लिए ऊपर बदल गया


1
PHP 7 में / zend.assertionsपूरी तरह से बंद करने के लिए ini सेटिंग होगी assert()
कंटोलफ्रीक

यह बहुत अच्छी खबर है - लेकिन प्रलेखन के आधार पर यह PHPUnit के लिए एक पैच की तरह लग रहा है, आर्डर को वापस लाना है। इस तरह से यूनिट परीक्षण एनोटेशन @ अनपेक्षित अपवाद AssertionException का उपयोग कर सकते हैं, भले ही वे PHP 5.x या 7. पर चलें
माइकल मोरिस

3

अभिकर्मक का उपयोग केवल विकास में किया जाना चाहिए क्योंकि यह डिबगिंग के लिए उपयोगी है। इसलिए यदि आप चाहते हैं कि आप उन्हें अपनी वेबसाइट विकसित करने के लिए उपयोग कर सकते हैं, लेकिन आपको एक लाइव वेबसाइट के लिए अपवादों का उपयोग करना चाहिए।


7
लेकिन एक अभी भी कोड में मुखर होगा। वे सिर्फ उत्पादन के माहौल में सक्रिय नहीं होंगे।
एरोनस्टरलिंग

1
मैं उन्हें उत्पादन में रखूंगा और अपनी त्रुटि हैंडलर को तदनुसार बदलूंगा।
डैनियल डब्लू।

3

नहीं, आपका सहकर्मी इसे सामान्य प्रयोजन त्रुटि हैंडलर के रूप में उपयोग नहीं कर रहा है। मैनुअल के अनुसार:

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

इनपुट पैरामीटर जांच जैसे सामान्य रनटाइम संचालन के लिए अभिकथन का उपयोग नहीं किया जाना चाहिए। अंगूठे के नियम के रूप में आपके कोड को हमेशा सही ढंग से काम करने में सक्षम होना चाहिए यदि अभिकथन जाँच सक्रिय नहीं है।

यदि आप स्वचालित परीक्षण सूट से परिचित हैं, तो "मुखर" क्रिया का उपयोग आमतौर पर किसी विधि या फ़ंक्शन के आउटपुट को सत्यापित करने के लिए किया जाता है। उदाहरण के लिए:

function add($a, $b) {
    return $a + $b;
}

assert(add(2,2) == 5, 'Two and two is four, dummy!');
assert(is_numeric(add(2,2)), 'Output of this function to only return numeric values.');

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


3

आप सहकर्मी वास्तव में अनुबंध द्वारा डिजाइन लागू करने का प्रयास कर रहे हैं में एफिल भाषा से (डीबीसी) हैं और पुस्तक के आधार पर: ऑब्जेक्ट ओरिएंटेड सॉफ्टवेयर कंस्ट्रक्शन, 2 डी संस्करण।

मुखरता, जैसा कि उन्होंने इसका इस्तेमाल किया, होरे लॉजिक या होरे ट्रिपल का {P} -पार्टर: {P} C {Q} होगा, जहां {P} प्रीकॉन्डिशन एसर (आयन) s और {Q} हैं स्थिति के बाद मुखर (आयन) एस।

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

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

अंत में - यदि आप अनुबंध द्वारा डिजाइन का एक अध्ययन करते हैं, तो आप पाएंगे कि ऑब्जेक्ट-ओरिएंटेड क्लासिकल इनहेरिटेंस के प्रकाश में बूलियन कथनों का उपयोग करने के परिणाम हैं - अर्थात् - आपको किसी पूर्व शर्त को कमजोर नहीं करना चाहिए, और न ही बाद की स्थिति को कमजोर करना चाहिए। ऐसा करना आपके बहुरूपी वंशजों के लिए खतरनाक हो सकता है जो आपस में बातचीत कर रहे हैं। जब तक आप समझते हैं कि इसका क्या मतलब है-मैं इसे अकेला छोड़ दूँगा!

इसके अलावा-मैं अत्यधिक अनुशंसा करता हूं कि PHP के निर्माता अनुबंध द्वारा डिजाइन का एक व्यापक अध्ययन करें और इसे PHP ASAP में डालने का प्रयास करें! तब हम सभी को एक DbC- जागरूक संकलक / दुभाषिया होने से लाभ हो सकता है, जो उत्तर में दिए गए मुद्दों को संभालेंगे (ऊपर):

  1. एक उचित रूप से लागू किया गया डिज़ाइन-बाय-कॉन्ट्रैक्ट-अवेयर कंपाइलर (उम्मीद है) बग-मुक्त (वर्तमान पीएचपी मुखर के विपरीत) होगा।
  2. एक उचित रूप से लागू किया गया डिज़ाइन-बाय-कॉन्ट्रैक्ट-अवेयर कंपाइलर इस मामले पर आपके दिमाग को रैक करने के बजाय आपके लिए बहुरूपी अभिकथन तर्क प्रबंधन की बारीकियों को हैंडल करेगा!

नोट: यहां तक ​​कि आपके एक का उपयोग if मुखर (पूर्व शर्त) के विकल्प के रूप में -statement के लिए एक पूर्व शर्त को मजबूत करने या एक पोस्ट-स्थिति को कमजोर करने के लिए उपयोग किए जाने पर गंभीर परिणाम भुगतने होंगे। यह समझने के लिए कि इसका क्या मतलब है, आपको पता करने के लिए अनुबंध द्वारा डिजाइन का अध्ययन करना होगा! :-)

हैप्पी अध्ययन और सीखने।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.