2009-03-25 10 views
19

नाम फ़ंक्शन पैरामीटर PHP में नकल करते किया जा सकता है अगर मैं इसके अलावा IDEs इस दृष्टिकोण के अन्य संभावित कमियां हैं क्या में IntelliSense खोने से इसपीएचपी, अच्छा या बुरा विचार में नामित फ़ंक्शन पैरामीटर का अनुकरण करना?

function pythonic(array $kwargs) 
{ 
    extract($kwargs); 
    // .. rest of the function body 
} 

// if params are optional or default values are required 
function pythonic(array $kwargs = array('name'=>'Jon skeet')) 
{ 
    extract($kwargs); 
    // .. rest of the function body 
} 

जैसे कार्यों के बारे में?

संपादित करें:

सुरक्षा: सुरक्षा, इस मामले में एक गैर मुद्दा नहीं करना चाहिए के रूप में निकाली गई चर गुंजाइश ढंग से काम करने के लिए सीमित कर रहे हैं?

उत्तर

33

मैं नामित पैरामीटर पास करने के लिए एसोसिएटिव सरणी का उपयोग करने का सुझाव दूंगा, लेकिन उन्हें निकालने के बिना उन्हें सरणी में रखें।

function myFunc(array $args) { 
    echo "Hi, " . $args['name']; 
    // etc 
} 

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

दूसरा, यह सुनिश्चित करता है कि अन्य कोड तर्कों को ओवरराइट नहीं करता है। आपने अपने कार्य को केवल $foo और $bar नामक तर्कों की अपेक्षा की हो सकती है, इसलिए उदाहरण के लिए, आप $baz = 8; को परिभाषित करते हैं। बाद में, हो सकता है कि आप "फ़ज़" नामक एक नया पैरामीटर लेने के लिए अपने फ़ंक्शन का विस्तार करना चाहें, लेकिन अपने अन्य चर बदलने के लिए भूल जाएं, इसलिए तर्कों में कोई फर्क नहीं पड़ता कि $baz हमेशा 8 पर सेट हो जाएगा।

वहां सरणी भी उपयोग के कुछ लाभ हैं (इन्हें निकालने या सरणी में छोड़ने के तरीकों के लिए समान रूप से लागू):

function myFunc (array $args) { 
    $default = array(
     "name" => "John Doe", 
     "age" => "30" 
    ); 
    // overwrite all the defaults with the arguments 
    $args = array_merge($defaults, $args); 
    // you *could* extract($args) here if you want 

    echo "Name: " . $args['name'] . ", Age: " . $args['age']; 
} 

myFunc(array("age" => 25)); // "Name: John Doe, Age: 25" 

तुम भी निकाल सकते: आप $defaults कहा जाता है प्रत्येक कार्य के शीर्ष पर एक चर सेट कर सकते हैं $args से सभी आइटम जिनके पास $default मान नहीं है। इस तरह आप जानते हैं कि आपके पास कौन से चर हैं।

+2

इसे संभालने का अच्छा तरीका। मुझे लिखने से पहले मुझे अपना जवाब नहीं पछतावा है। – Rolf

6

मेरे अनुभव में, इस दृष्टिकोण वास्तव में अगर दो चीजों में से एक सच

  1. जो कुछ हल्का करने वाली कारणों के लिए है ही फायदेमंद है, अपने तर्क हस्ताक्षर बड़ा है। मैं थोड़े से 6 तक जाता हूं - किसी विशेष कारण के लिए नहीं, हालांकि सही लगता है - लेकिन मैं स्वतंत्र रूप से स्वीकार करता हूं कि यह संख्या मनमानी है।
  2. आपके सभी या कई तर्क वैकल्पिक हैं, और कभी-कभी आपको केवल 5 वें या कुछ ऐसी चीज़ के लिए मूल्य निर्धारित करने की आवश्यकता होती है। someFunc(null, null, null, null, 1);

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

कहा जा रहा है कि कई बार इन दोनों समस्याओं को रिफैक्टरिंग के माध्यम से हल किया जा सकता है।

8

यह एक और तरीका है जिससे आप ऐसा कर सकते हैं।

/** 
* Constructor. 
* 
* @named string 'algorithm' 
* @named string 'mode' 
* @named string 'key' 
*/ 
public function __construct(array $parameter = array()) 
{ 
    $algorithm = 'tripledes'; 
    $mode = 'ecb'; 
    $key = null; 
    extract($parameter, EXTR_IF_EXISTS); 
    //... 
} 

इस के साथ की स्थापना की, आप डिफ़ॉल्ट पैरामीटर मिलता है, आप IDEs और EXTR_IF_EXISTS में IntelliSense खोना नहीं है यह सिर्फ सरणी कुंजी कि पहले से ही चर के रूप में मौजूदा कर रहे हैं निकाल कर सुरक्षित बनाता है।

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

+0

क्या यह उन कार्यों के लिए काम करेगा जो कक्षा के तरीके नहीं हैं? (डिफ़ॉल्ट मान पर: मुझे यह भी प्रश्न पोस्ट करने के बाद मिला) – Imran

+0

निश्चित रूप से, यह मेरी एक कक्षा का सिर्फ एक स्निपेट है। यह किसी भी चीज़ के लिए काम करता है। – Mario

+1

कृपया आप बता सकते हैं कि 'नामित' टैग के साथ इंटेलिजेंस कैसे काम करना है? मैं PHPStorm का उपयोग कर रहा हूं, जिसमें उत्कृष्ट इंटेलिजेंस है, लेकिन मुझे इसे 'नामित' टैग को पहचानने के लिए नहीं मिल रहा है। मुझे नहीं लगता कि यह एक "वास्तविक" PHP टिप्पणी टैग है, है ना? यह [टैग की PHPDoc सूची] में नहीं है (http://www.phpdoc.org/docs/latest/index.html) – Rich

2

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

function someFunc($requiredArg, $arg1 = "default11", $arg2 = "default2") { 

इस व्यवहार अनुकरण करने के लिए, और "समारोह हस्ताक्षर" कम "स्पष्ट और स्पष्ट" हो जाएगा।

function someFunc($requiredArg, $optionalArgs) { 
    // see other answers for good ways to simulate "named parameters" here 

मैं अगर यह एक अच्छा विचार पीएचपी एक भविष्य के रिलीज में संबोधित करने के लिए के लिए है कि हो सकता है सोच रहा हूँ, शायद पास्कल या VB वाक्य रचना समारोह तर्क के लिए उपलब्ध की तरह कुछ है।

वैसे भी, मैं केवल एक ही सरणी में पैरामीटर पास करता हूं जब वास्तव में आवश्यकता होती है - ऐसे फ़ंक्शन जो पैरामीटर सेट रखते हैं जो विकास के दौरान बहुत कुछ बदल सकते हैं। इन कार्यों में आमतौर पर कई पैरामीटर भी होते हैं।

1

अन्य लोगों ने आपके अन्य बिंदुओं का उत्तर दिया है, मैं केवल सुरक्षा पहलू पर टिप्पणी करना चाहूंगा।

सुरक्षा: सुरक्षा, इस मामले में एक गैर मुद्दा नहीं करना चाहिए के रूप में निकाले चर गुंजाइश ढंग से काम करने के लिए सीमित कर रहे हैं?

हां और नहीं। आपके द्वारा लिखे गए कोड (इस कॉल के बाद आप हमेशा अपने चर को प्रारंभ करते हैं या नहीं) इस पर निर्भर करता है कि आपके वर्रों को ओवरराइट करें। उदाहरण:

function pythonic(array $kwargs = array('name'=>'Jon skeet')) 
{ 
    $is_admin = check_if_is_admin(); // initialize some variable... 

    extract($kwargs); 

    // Q: what is the value of $is_admin now? 
    // A: Depends on how this function was called... 
    // hint: pythonic([ 'is_admin' => true ]) 
} 

क्या इस कोड को "प्रकार के- सुरक्षित" यह है कि आप एक है जो यह बुला रहा है कर रहे हैं बनाता है - तो उपयोगकर्ता मनमाना पैरामीटर की आपूर्ति नहीं कर सकते हैं (जब तक आप अनुप्रेषित पोस्ट वहाँ वार्स, ज़ाहिर है;)।

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

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