वैकल्पिक पैरामीटर के साथ PHP फ़ंक्शन


107

मैंने एक PHP फ़ंक्शन लिखा है जो 10 मापदंडों को स्वीकार कर सकता है, लेकिन केवल 2 की आवश्यकता है। कभी-कभी, मैं आठवें पैरामीटर को परिभाषित करना चाहता हूं, लेकिन जब तक मैं आठवें तक नहीं पहुंचता, मैं प्रत्येक पैरामीटर के लिए खाली तारों में टाइप नहीं करना चाहता।

एक विचार मेरे पास एक अमूर्त फ़ंक्शन को पास करने के लिए था, जिसमें एक पैरामीटर था जो इसे वास्तविक फ़ंक्शन के साथ गुजरता है।

क्या फ़ंक्शन स्थापित करने का एक बेहतर तरीका है, इसलिए मैं केवल उन मापदंडों को पारित कर सकता हूं जो मुझे चाहिए?


4
संबंधित: stackoverflow.com/questions/2112913
Pekka

वह अजीब है। Php में अंतर्निहित कार्यों में वैकल्पिक पैरामीटर हो सकते हैं। तो हम उस तरह के कार्यों का निर्माण क्यों नहीं कर सकते?
रॉड्रिगो

2
ध्यान दें कि इनमें से कई उत्तर OUTDATED हैं ... PHP अब चर-लंबाई तर्क सूचियों के साथ फ़ंक्शन का समर्थन करता है
ashleedawg

जवाबों:


62

फ़ंक्शन को एक पैरामीटर लें: एक सरणी। सरणी में मान के रूप में वास्तविक मापदंडों में पास करें।


संपादित करें: Pekka की टिप्पणी में लिंक बस इसे sums के बारे में।


1
वह अजीब है। Php में अंतर्निहित कार्यों में वैकल्पिक पैरामीटर हो सकते हैं। तो हम उस तरह के कार्यों का निर्माण क्यों नहीं कर सकते?
रॉड्रिगो

1
@ रोड्रिगो यह उन जैसे कार्यों को परिभाषित करने के लिए बिल्कुल उपयुक्त है। वे हालांकि वैकल्पिक वैकल्पिक हैं, जो एक एकल वैकल्पिक पैरामीटर से परे किसी भी चीज के लिए बहुत ही घटिया है।
मैट बॉल

1
ठीक है, मैं [] के साथ कोशिश कर रहा था, अब मैं देखता हूं कि यह कैसे करना है: stackoverflow.com/a/34869/1086511
रॉड्रिगो

ऐसा और भी हो सकता है कि सिर्फ "एक सरणी का उपयोग करें" सुझाव - एक समान प्रश्न के वाल्फ के जवाब पर एक नज़र डालें और एक ही धागे में अधिक गहराई से उदाहरण
डीजेडेव

63

मैंने इस मामले में जो किया है वह एक सरणी है, जहां कुंजी पैरामीटर नाम है, और मूल्य मान है।

$optional = array(
  "param" => $param1,
  "param2" => $param2
);

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}

आपके उदाहरण के लिए, $ वैकल्पिक को फ़ंक्शन के भीतर वैश्विक सेट करने की आवश्यकता नहीं होगी?
user481826

1
वैश्विक? नहीं..? आप फ़ंक्शन को कॉल करने से पहले उस सरणी को बनाते हैं, और आप इसे पास करते हैं। मेरा कोड मैट बॉल्स का एक उदाहरण है कि क्या किया जाना चाहिए।
Rabbott

ऐसा और भी हो सकता है कि सिर्फ "एक सरणी का उपयोग करें" सुझाव - एक समान प्रश्न के वाल्फ के जवाब पर एक नज़र डालें और एक ही धागे में अधिक गहराई से उदाहरण
डीजेडेव

45

आप जो चाहते हैं उसे पूरा करने के लिए, एक सरणी का उपयोग करें जैसे Rabbot ने कहा (हालाँकि यह दस्तावेज़ के लिए एक दर्द बन सकता है / यदि इसका उपयोग अत्यधिक किया जाता है)। या बस पारंपरिक वैकल्पिक args का उपयोग करें।

//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
  //Do stuff
}
my_func('Hi', 'World', null, null, 'Red');

हालाँकि, मुझे आमतौर पर लगता है कि जब मैं एक फ़ंक्शन / पद्धति लिखना शुरू करता हूं, तो कई तर्क - अधिक बार नहीं यह एक कोड गंध है, और कुछ अधिक क्लीनर में फिर से फैक्टर / सार हो सकता है।

//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
  return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');

2010 में, 'कोड गंध', 'रिफैक्टिंग' या 'कोड रखरखाव' जैसी धारणाएं हमारे समुदाय में लोकप्रिय नहीं थीं। आप में से ज्यादातर से पहले एक कदम था :)
बिलल बेगुएरदज

15

PHP 5.6 और बाद में, तर्क सूचियों में शामिल हो सकता है ... token यह निरूपित करने के लिए कि फ़ंक्शन तर्कों की एक चर संख्या को स्वीकार करता है। दिए गए चर में तर्कों को एक सरणी के रूप में पारित किया जाएगा; उदाहरण के लिए:

उदाहरण का उपयोग ... चर तर्कों का उपयोग करने के लिए

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

उपरोक्त उदाहरण आउटपुट करेगा:

10

चर-लंबाई तर्क PHP दस्तावेज़ीकरण को सूचीबद्ध करता है


यह प्रतिक्रिया अधिक अंक की हकदार है। मेरे विशिष्ट मामले के परिदृश्य के लिए उपयुक्त नहीं, लेकिन अच्छी जानकारी और समझने में सरल। PHP 7.3 जल्द ही आ रहा है! 5.6 और 7 ईओएल हैं।
AdheneManx

12

आप डिफ़ॉल्ट मान को शून्य करने के लिए सेट कर सकते हैं।

<?php
function functionName($value, $value2 = null) {
// do stuff
}

2
सबसे अच्छा उत्तर, लेकिन कृपया nullतारीख के प्रकार के गैर-बिट्स के साथ बदलें । उदाहरणों array()के लिए उदाहरण के लिए
मोहम्मद हिचम

धन्यवाद ... यह वही है जिसकी मैं तलाश कर रहा था
डेविद डी मैस्त्री

12

नोट: यह PHP 5.5 और उससे नीचे के लिए, एक पुराना उत्तर है । PHP 5.6+ डिफ़ॉल्ट तर्कों का समर्थन करता है

PHP 5.5 और नीचे में, आप इन 2 विधियों में से किसी एक का उपयोग करके इसे प्राप्त कर सकते हैं:

  • का उपयोग कर func_num_args () और func_get_arg () कार्य;
  • NULL तर्कों का उपयोग करना;

कैसे इस्तेमाल करे

function method_1()
{
  $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
  $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}

function method_2($arg1 = null, $arg2 = null)
{
  $arg1 = $arg1? $arg1: "default_value_for_arg1";
  $arg2 = $arg2? $arg2: "default_value_for_arg2";
}

मैं दूसरी विधि पसंद करता हूं क्योंकि यह साफ और समझने में आसान है, लेकिन कभी-कभी आपको पहली विधि की आवश्यकता हो सकती है।


1
आपको यहां डबल "=" की आवश्यकता है या सभी अभिव्यक्तियां सच हो जाएंगी। इसके अलावा, 2 उदाहरण में अभिव्यक्तियाँ हमेशा सही होंगी क्योंकि एक चर हमेशा खुद के बराबर होता है।
chuckieDub

अच्छी बात है, लेकिन यह वास्तव में काम करता है। PHP में यह कोड $x = null; if ($x) echo "true"; else echo "false";"गलत" प्रिंट करेगा, भले ही $ x var का इस कोड में मान हो ("null")। इसके अलावा, दोनों तरीकों में हम टर्नरी ऑपरेटर का उपयोग कर रहे हैं, इसलिए यह सिर्फ एक "=" का सही उपयोग है। यदि आप के साथ परीक्षण करते हैं method(); method(1); method(1, 2);, तो पहली कॉल arg1 और arg2 को डिफॉल्ट्स मानों के साथ जोड़ेगी, दूसरी कॉल दूसरे arg को डिफ़ॉल्ट मान के साथ जोड़ेगी और पहले arg के लिए "1"। अंतिम कॉल डिफ़ॉल्ट मानों को संबद्ध नहीं करेगी।
डैनियल लौरेइरो

1
function मेथड_2 ($ arg1 = "default_value_fot_arg1", $ arg2 = "default_value_fot_arg2") {तो सामान सामान के साथ php सौदा करें और यह भी कि आप पैरामीटर को पास कर सकते हैं (क्यों लोग null I का उपयोग नहीं करते हैं)
nerkn

1
@nerkn, आप सही हैं, PHP वर्तमान में डिफ़ॉल्ट तर्कों का समर्थन करता है। लोल, मुझे याद है कि जब हमें सरल चीजों को प्राप्त करने के लिए बहुत अधिक कार्य-प्रणाली बनाने की आवश्यकता थी। अच्छा समय: पी आप अभी भी पुराने कोड (5.5 पूर्व) में उन तरीकों को देख सकते हैं।
डैनियल लौरेइरो

4

मुझे लगता है, आप वस्तुओं का उपयोग परम-परिवहन के रूप में भी कर सकते हैं।

$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);

function theFunction($fparam){      
  return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}

बेशक, आपको इस फ़ंक्शन में "optParam8" और "optParam2" के लिए डिफ़ॉल्ट मान सेट करने होंगे, दूसरे मामले में आपको "सूचना: अपरिभाषित संपत्ति: stdClass :: $ optParam2" मिल जाएगी।

यदि फ़ंक्शन पैरामीटर के रूप में सरणियों का उपयोग किया जाता है, तो मुझे डिफ़ॉल्ट मान सेट करने का यह तरीका पसंद है:

function theFunction($fparam){
   $default = array(
      'opt1' => 'nothing',
      'opt2' => 1
   );
   if(is_array($fparam)){
      $fparam = array_merge($default, $fparam);
   }else{
      $fparam = $default;
   }
   //now, the default values are overwritten by these passed by $fparam
   return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}

2

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

आगे की पढाई


2

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मुझे ओपी की तरह एक समस्या हो रही थी और यह वही है जिसके साथ मैं आया था।

सरणी के उदाहरण आप पारित कर सकते हैं। यदि आप एक विशेष आदेश की आवश्यकता थी, तो आप इसे फिर से ऑर्डर कर सकते हैं, लेकिन इस प्रश्न के लिए यह वही होगा जो पूछा जाता है।

$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');

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

आसानी के लिए इसे बाहरी फाइल में चिपका दें

function unknown_number_arguments($argument_set) {

    foreach ($argument_set as $key => $value) {

        # create a switch with all the cases you need. as you loop the array 
        # keys only your submitted $keys values will be found with the switch. 
        switch ($key) {
            case 1:
                # do stuff with $value
                break;
            case 2:
                # do stuff with $value;
                break;
            case 3:
                # key 3 omitted, this wont execute 
                break;
            case 5:
                # do stuff with $value;
                break;
            case 8:
                # do stuff with $value;
                break;
            default:
                # no match from the array, do error logging?
                break;
        }
    }
return;
}

अगर फ़ाइल शुरू में इसे रखो।

$argument_set = array(); 

डेटा कहाँ से आ रहा है उसी के अनुसार डेटा उपयोग नंबरिंग / नामकरण के अगले टुकड़े को असाइन करने के लिए इनका उपयोग करें।

$argument_set[1][] = $some_variable; 

और अंत में एरे पास करें

unknown_number_arguments($argument_set);

1
function yourFunction($var1, $var2, $optional = Null){
   ... code
}

आप एक नियमित कार्य कर सकते हैं और फिर उन्हें एक डिफ़ॉल्ट अशक्त मान देकर अपने वैकल्पिक चर जोड़ सकते हैं।

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


2
क्या आप उसे आगे समझा सकते हैं? दिया गया कोड वाक्यविन्यास रूप से अमान्य है, क्योंकि चर नाम किसी संख्या से शुरू नहीं हो सकते हैं
निको हसे

0

यदि आप आम तौर पर सिर्फ 8 वें मूल्य में पास कर रहे हैं, तो आप अपने मापदंडों को फिर से व्यवस्थित कर सकते हैं, इसलिए यह पहले है। आपको केवल वही पैरामीटर निर्दिष्ट करने की आवश्यकता है, जब तक कि आप जो अंतिम सेट करना चाहते हैं।

यदि आप विभिन्न मानों का उपयोग कर रहे हैं, तो आपके पास 2 विकल्प हैं।

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

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


0

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

उदाहरण के लिए:

<?php
  function yourFunction($arg1, $arg2, $arg3=NULL, $arg4=NULL, $arg5=NULL, $arg6=NULL, $arg7=NULL, $arg8=NULL){
echo $arg1;
echo $arg2;
if(isset($arg3)){echo $arg3;}
# other similar statements for $arg4, ...., $arg5
if(isset($arg8)){echo $arg8;}
}

दिलचस्प विचार ... हालाँकि आपका प्रस्ताव समस्या का समाधान नहीं करता है। वास्तव में, यदि आप इस बात की जानकारी जोड़ते हैं कि किस तर्क को प्रतिध्वनित किया जा रहा है (जैसे उपयोग करके echo " this is arg3: " . $arg3;, आदि), तो आप देखेंगे कि कॉलिंग जैसे yourFunction(3, 2, $arg8=5);प्रिंट होगा 32 this is arg3: 5। समस्या यह है कि पैरामीटर स्थिति अभी भी मायने रखती है जब PHP में वैकल्पिक मापदंडों को पारित कर रहा है ... पैरामीटर नाम पैरामीटर नामों के पैरामीटर मानों को मैप करने के लिए पर्याप्त नहीं हैं
मस्तूरी

0

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

 function myFunc($p1,$p2,$p3=Null,$p4=Null,$p5=Null,$p6=Null,$p7=Null,$p8=Null){
    for ($i=1; $i<9; $i++){
        $varName = "p$i";
        if (isset($$varName)){
            echo $varName." = ".$$varName."<br>\n";
        }
    }
}   

myFunc( "1", "2", Null, Null, Null, Null, Null, "eight" );

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