2012-04-17 19 views
10

मुझे व्यक्तिगत पैरामीटर के बजाय तर्क के रूप में key => वैल्यू जोड़े (सरणी) का उपयोग करके अपने PHP फ़ंक्शन बनाना पसंद है।PHP फ़ंक्शन तर्क - एक सरणी का उपयोग करें या नहीं?

उदाहरण के लिए, मैं पसंद करते हैं:

function useless_func($params) { 
    if (!isset($params['text'])) { $params['text'] = "default text"; }  
    if (!isset($params['text2'])) { $params['text2'] = "default text2"; } 
    if (!isset($params['text3'])) { $params['text3'] = "default text3"; } 
    echo $params['text'].$params['text2'].$params['text3']; 
    return; 
} 

और मुझे पसंद नहीं है:

function useless_func($text = "default text", $text2 = "default text2", $text3 = "default text3") { 
     echo $text.$text2.$text3; 
    return; 
} 

मैं पहली बार देखा था बातें Wordpress codebase में इस तरह बड़े पैमाने पर किया।

कारण मैं सरणियों पसंद करते हैं:

  • समारोह तर्क, किसी भी क्रम
  • आसान कोड/अधिक आत्म दस्तावेज़ीकृत कर (मेरी राय में) को पढ़ने के लिए
  • कम गलतियाँ में प्रदान किया जा सकता है क्योंकि जब एक समारोह चाहिए बुला मैं जांच उचित सरणी कुंजी

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

मैं उन विशेषज्ञों से कुछ सामान्य सलाह और मार्गदर्शन ढूंढ रहा हूं जो अंतर्दृष्टि प्रदान करने में सक्षम हो सकते हैं: ऐसा करने का बेहतर या अधिक उचित तरीका क्या है?

+0

मुझे समझ नहीं आता क्यों लोग भले ही किसी को एक ढांचा है जिसके raw_queries लेता विकासशील अपने function.I'm पर काम कर रहा है, जिस तरह से आप है mentioned.I लगता है कि यह एक लचीला तरीका है गुजर के खिलाफ ज्यादातर रहे हैं, और कुछ और चीजें। और पैरामीटर की सरणी को पार्स करने की क्षमता इसे बहुत लचीला बनाती है। – DaAmidza

उत्तर

15

अच्छा, यह थोड़े उपयोगी है। लेकिन कुछ तर्क जो हमेशा गुज़र रहे हैं, क्लासिक पासिंग का उपयोग करना बेहतर है जैसे function some($a1, $a2)। मैं अपने कोड में इस तरह कर रहा हूँ:

function getSome(SomeClass $object, array $options = array()) 
{ 
    // $object is required to be an instance of SomeClass, and there's no need to get element by key, then check if it's an object and it's an instance of SomeClass 

    // Set defaults for all passed options 
    $options = array_merge(array(
     'property1' => 'default1', 
     'property2' => 'default2', 
     ... => ... 
    ), $options); 
} 

तो, आप मुझे लगता है कि कोड शैली भी पसंद है, लेकिन कोर-तर्क के लिए मैं क्योंकि इस तरह पीएचपी और बातें जो मैं करना चाहिए नियंत्रित करता है, क्लासिक शैली पसंद करते देख सकते हैं , अगर मैंने आपको कोड शैली का उपयोग किया था।

+0

"कोर" तर्क व्यक्तिपरक हैं और तर्कों की क्रिसमस सूची का कारण बन सकते हैं। यदि आप 2 से अधिक के कठिन और तेज़ नियम का पालन करते हैं, तो सरणी होनी चाहिए, भले ही कोर या नहीं। –

0

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

निश्चित रूप से यह सरणी से मूल्यों को निकालने के लिए थोड़ा और अधिक काम करता है, और आपको आवश्यक तत्वों के लिए खाते हैं, लेकिन यह सुविधाओं को जोड़ने में बहुत आसान बनाता है, और फ़ंक्शन में 13 तर्कों को पार करने से कहीं बेहतर है हर बार इसे बुलाया जाना चाहिए।

// Class will tokenize a string based on params 
public static function tokenize(array $params) 
{ 
    // Validate required elements 
    if (!array_key_exists('value', $params)) { 
     throw new Exception(sprintf('Invalid $value: %s', serialize($params))); 
    }   

    // Localize optional elements 
    $value   = $params['value']; 
    $separator  = (array_key_exists('separator', $params)) ? $params['separator'] : '-'; 
    $urlEncode  = (array_key_exists('urlEncode', $params)) ? $params['urlEncode'] : false; 
    $allowedChars  = (array_key_exists('allowedChars', $params)) ? $params['allowedChars'] : array(); 
    $charsToRemove = (array_key_exists('charsToRemove', $params)) ? $params['charsToRemove'] : array(); 

.... 
5

आपका सहकर्मी सही है:

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

+0

आप ऊपर @devdRew देखा, तो आप कह सकते हैं कि array_merge() फ़ंक्शन अभी भी के लिए "धीमे" पानी पकड़ होता है कि? – ethanpil

+0

कि के "होली युद्ध" प्रकार है, का उपयोग करें या नहीं करने के लिए सरणी तर्कों में एकत्रित का उपयोग करने, लेकिन अगर आप कह रहे हैं इसे पारित मूल्यों के साथ डेटाबेस के लिए कुछ रिकॉर्ड के भंडारण के लिए उदाहरण के लिए, अलग तर्कों का उपयोग करना अधिक आसान है, तुम नहीं एक अलग तर्क के रूप में प्रत्येक पंक्ति मान के लिए उपयोग करें। सही? – devdRew

9

मैं तुम्हें पूछ रहे हैं कि क्या यह एक अच्छी बात है सभी कार्यों लिखने के लिए इतना है कि वे केवल एक ही तर्क को स्वीकार संभालने कर रहा हूँ, और कहा कि तर्क के लिए एक श्रृंखला होना चाहिए?

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

मैं अनुशंसा करता हूं कि सरणी पैरामीटर या तो उन वस्तुओं के लिए आरक्षित हैं जहां आप नहीं जानते कि कितने होंगे (उदाहरण के लिए डेटा आइटम की एक श्रृंखला), या संबंधित विकल्पों/सेटिंग्स के समूहों के लिए (जो हो रहा है वर्डप्रेस उदाहरण में आप उल्लेख करते हैं?)।

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

+0

मुझे लगता है कि उचित दस्तावेज सर्वर को उस मुद्दे का मुकाबला करने के लिए एक बहुत ही वैध "कदम के रूप में सर्वर कर सकता है।" – ethanpil

+0

मैंने सुना है आप क्या कह रहे हैं, लेकिन अगर अपने कोड अच्छी तरह से लिखा है, यह ज्यादातर आत्म दस्तावेज़ीकृत कर, जिस स्थिति में आप 'दस्तावेज़' यह (जैसे टिप्पणी के साथ आदि) की जरूरत नहीं है होना चाहिए। यह उन मुद्दों को हल करता है जो कोड को 'दस्तावेज़' के साथ समन्वयित होने पर फसल कर सकते हैं। – Squig

4

Cargo Cult programming पर यह सीमाएं। आप कहते हैं कि यह अधिक पठनीय और स्वयं-दस्तावेज है। मैं पूछूंगा कि कैसे? अपने फ़ंक्शन/विधि का उपयोग करने के बारे में जानने के लिए मुझे कोड में ही पढ़ना होगा। इस बात का कोई तरीका नहीं है कि मैं इसे हस्ताक्षर से कैसे उपयोग कर सकता हूं। यदि आप किसी अर्ध-सभ्य आईडीई या संपादक का उपयोग करते हैं जो विधि हस्ताक्षर का समर्थन करता है तो यह एक वास्तविक पिटा होगा। इसके अलावा आप PHP के प्रकार-संकेत वाक्यविन्यास का उपयोग करने में सक्षम नहीं होंगे।

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

4

array_merge() का उपयोग ठीक काम करता है, लेकिन + ऑपरेटर का उपयोग भी किया जा सकता है; यह दूसरी तरफ काम करता है, यह केवल डिफ़ॉल्ट मान जोड़ता है जहां अभी तक कोई नहीं दिया गया है।

function useless_func(array $params = array()) 
{ 
    $params += array(
     'text' => 'default text', 
     'text2' => 'default text2', 
     'text3' => 'default text3', 
    ); 
} 

यह भी देखें: Function Passing array to defined key

कुछ बातें आप समारोह तर्कों के रूप सरणियों उपयोग करने के साथ नहीं मिलता है:

  1. प्रकार की जाँच (केवल वस्तुओं और सरणियों के लिए लागू है, लेकिन यह कर सकते हैं उपयोगी हो और कुछ मामलों में अपेक्षित)।
  2. स्मार्ट (एआर) टेक्स्ट एडिटर्स में एक कोड अंतर्दृष्टि सुविधा है जो एक समारोह को समझने वाले तर्क दिखाएगा; सरणी का उपयोग उस सुविधा को दूर ले जाता है, हालांकि आप फंक्शन डॉकब्लॉक में संभावित कुंजी जोड़ सकते हैं।
  3. # 2 के कारण यह वास्तव में अधिक त्रुटि प्रवण हो जाता है, क्योंकि आप सरणी कुंजी को गलत टाइप कर सकते हैं।
0

@Mike, आप भी "निकालने()" कर सकता है अपने स्थानीय चर में $ पैरामीटर तर्क, इस तरह:

// Class will tokenize a string based on params 
public static function tokenize(array $params) 
{ 
    extract($params); 
    // Validate required elements 
    if (!isset($value)) { 
     throw new Exception(sprintf('Invalid $value: %s', serialize($params))); 
    } 

    // Localize optional elements 
    $value   = isset($value) ? $value : ''; 
    $separator  = isset($separator) ? $separator] : '-'; 
    $urlEncode  = isset($urlEncode) ? $urlEncode : false; 
    $allowedChars = isset($allowedChars) ? $allowedChars : array(); 
    $charsToRemove = isset($charsToRemove) ? $charsToRemove : array(); 

....

ही कार्यान्वयन, लेकिन छोटे।

0

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

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

function ($a1, $a2, ... $a10){ 

     if($a1 == "Y"){$clause_1 = " something = ".$a1." AND ";} 
     ... 
     if($a10 == "Y"){$clause_10 = " something_else = ".$a10." AND ";} 

     $sql = " 
     SELECT * FROM some_table 
     WHERE 
     ".$clause_1." 
     .... 
     ".$clause_10." 
     some_column = 'N' 
     "; 

     return $sql; 
    } 

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

+0

यदि फ़ंक्शन में 10 तर्क हैं, तो यह संभवतः खराब तरीके से डिज़ाइन किया गया है और इसे पुनर्विचार किया जाना चाहिए। –

11

ऐसा मत करो!

एक सरणी में सभी को पास करना ज्यादातर समय एक बुरा विचार है।

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

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

समारोह तर्क किसी भी क्रम

मैं ऐसी कोई प्राथमिकता है में प्रदान की जा सकती है। मुझे जरूरत नहीं है।

आसान कोड/अधिक आत्म दस्तावेज़ीकृत कर (मेरी राय में)

अधिकांश IDEs अलग तर्क एक समारोह की जरूरत के साथ पेश करेंगे पढ़ने के लिए। यदि कोई foo(Someclass $class, array $params, $id) जैसे फ़ंक्शन घोषणा को देखता है तो यह बहुत स्पष्ट है कि फ़ंक्शन की क्या ज़रूरत है। मैं असहमत हूं कि एक भी सर्वो तर्क पढ़ने या स्वयं दस्तावेज करना आसान है।

कम गलतियाँ

, क्योंकि मैं उचित सरणी कुंजी

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


समस्या को हल करने की कोशिश कर रहे तर्कों की किसी भी बड़ी संख्या है, तो सही फैसला, छोटे में अपने फ़ंक्शन refactor समारोह निर्भरता एक सरणी के पीछे छिपा नहीं है।

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