एक फ़ंक्शन में डिफ़ॉल्ट तर्क का उपयोग करना


177

मैं PHP कार्यों के लिए डिफ़ॉल्ट मानों के बारे में उलझन में हूं। कहो मेरे पास एक समारोह है:

function foo($blah, $x = "some value", $y = "some other value") {
    // code here!
}

क्या होगा अगर मैं $ x के लिए डिफ़ॉल्ट तर्क का उपयोग करना चाहता हूं और $ y के लिए एक अलग तर्क सेट करना चाहता हूं?

मैं अलग-अलग तरीकों से प्रयोग कर रहा हूं और मैं सिर्फ भ्रमित हो रहा हूं। उदाहरण के लिए, मैंने इन दोनों को आजमाया:

foo("blah", null, "test");
foo("blah", "", "test");

लेकिन उन दोनों का परिणाम $ x के लिए उचित डिफ़ॉल्ट तर्क में नहीं होता है। मैंने इसे चर नाम से भी सेट करने की कोशिश की है।

foo("blah", $x, $y = "test");   

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


68
आप शायद कुछ भी याद नहीं कर रहे हैं, PHP डेवलपर्स शायद यह याद किया।
मैटी विर्ककुनेन

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

3
कुछ समय में मैंने सबसे अच्छे प्रश्नों में से एक देखा है! क्या आपने कुछ नहीं करने की कोशिश की है? foo("blah", , "test");?
मदारा का भूत

2
नियम यह है कि डिफ़ॉल्ट तर्क केवल तर्कों का पालन कर सकते हैं। यह है कि आप फू ("ब्ला") और x, y डिफ़ॉल्ट हैं, या फू ("ब्लाह", "xyz") और y डिफ़ॉल्ट हो सकते हैं।
माउस फूड

1
अपेक्षित् व्यवहार। "डिफ़ॉल्ट तर्क मान" अनुभाग देखें: php.net/manual/en/functions.arguments.php - शून्य मान और रिक्त स्ट्रिंग फ़ंक्शन के लिए वास्तविक तर्क के रूप में स्वीकार किए जाते हैं
jmdavalos

जवाबों:


164

मैं फ़ंक्शन घोषणा को इस प्रकार बदलना चाहूंगा ताकि आप वह कर सकें जो आप चाहते हैं:

function foo($blah, $x = null, $y = null) {
    if (null === $x) {
        $x = "some value";
    }

    if (null === $y) {
        $y = "some other value";
    }

    code here!

}

इस तरह, आप जैसे चाहें कॉल कर सकते हैं foo('blah', null, 'non-default y value');और यह काम कर सकते हैं, जहां दूसरा पैरामीटर $xअभी भी अपना डिफ़ॉल्ट मूल्य प्राप्त करता है।

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

जैसा कि अन्य उत्तरों में कहा गया है,

डिफ़ॉल्ट पैरामीटर केवल फ़ंक्शन के अंतिम तर्क के रूप में काम करते हैं। यदि आप फ़ंक्शन परिभाषा में डिफ़ॉल्ट मानों को घोषित करना चाहते हैं, तो एक पैरामीटर को छोड़ना और उसके बाद किसी को ओवरराइड करने का कोई तरीका नहीं है।

यदि मेरे पास कोई ऐसा तरीका है जो विभिन्न प्रकार के मापदंडों, और भिन्न प्रकारों के मापदंडों को स्वीकार कर सकता है, तो मैं अक्सर रयान पी द्वारा दिखाए गए उत्तर के समान फ़ंक्शन की घोषणा करता हूं।

यहाँ एक और उदाहरण है (यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन उम्मीद है कि जानकारीपूर्ण है:

public function __construct($params = null)
{
    if ($params instanceof SOMETHING) {
        // single parameter, of object type SOMETHING
    } else if (is_string($params)) {
        // single argument given as string
    } else if (is_array($params)) {
        // params could be an array of properties like array('x' => 'x1', 'y' => 'y1')
    } else if (func_num_args() == 3) {
        $args = func_get_args();

        // 3 parameters passed
    } else if (func_num_args() == 5) {
        $args = func_get_args();
        // 5 parameters passed
    } else {
        throw new InvalidArgumentException("Could not figure out parameters!");
    }
}

$ X = isset ($ x) क्यों नहीं है? $ x: 'डिफ़ॉल्ट मान'; ?
zloctb

@zloctb यह एक साफ और पठनीय अशक्त जाँच है। ऐसा लगता है कि यह डेवलपर प्राथमिकता है। या तो $ x = isset ($ x)? $ x: 'डिफ़ॉल्ट मान'; या $ x = is_null ($ x)? 'डिफ़ॉल्ट मान': $ x; इस समाधान के रूप में अच्छी तरह से काम करेगा। यह पठनीयता और रखरखाव के बारे में एक पसंद है।
डेवलपर

9
बस भविष्य के पाठकों के लिए स्पष्ट करने के लिए। पहला समाधान स्पष्ट रूप से nullपैरामीटर के लिए एक वास्तविक मूल्य निर्दिष्ट करना असंभव बनाता है , क्योंकि हर बार यह डिफ़ॉल्ट मान असाइन करेगा। यहां तक ​​कि अगर आपके पास एक और विशेष मूल्य है, जब आप वास्तव में एक शून्य चाहते हैं (जैसे कि जब $ x == "यूज़_नॉल" $ x = null करें), तो आप ऐसे विशेष मूल्य को शाब्दिक मान के रूप में निर्दिष्ट नहीं कर पाएंगे। पैरामीटर (इस मामले में, "use_null" स्ट्रिंग)। तो जब आप डिफ़ॉल्ट मान का उपयोग करना चाहते हैं (और आप nullएक वैध विकल्प बनना चाहते हैं) के लिए बस एक अद्वितीय, कभी वांछित "कुंजी" का उपयोग करना सुनिश्चित करें
डिएगोडीडी

37

वैकल्पिक तर्क केवल एक फ़ंक्शन कॉल के अंत में काम करते हैं। $ X को निर्दिष्ट किए बिना आपके फ़ंक्शन में $ y के लिए मान निर्दिष्ट करने का कोई तरीका नहीं है। कुछ भाषाएं नामांकित मापदंडों (उदाहरण के लिए VB / C #) के माध्यम से इसका समर्थन करती हैं, लेकिन PHP नहीं।

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

function foo(array $args = array()) {
    $x = !isset($args['x']) ? 'default x value' : $args['x'];
    $y = !isset($args['y']) ? 'default y value' : $args['y'];

    ...
}

फिर फ़ंक्शन को कॉल करें:

foo(array('y' => 'my value'));

1
आपकी स्थिति वास्तव में होनी चाहिए isset($args['x']), क्योंकि यह वर्तमान में एक खाली स्ट्रिंग, खाली सरणी, या falseडिफ़ॉल्ट मान के साथ बदल देगा।
टिम कूपर

@TimCooper lol मैं आपकी पहली टिप्पणी के आधार पर परिवर्तन करने के लिए गया था कि यह '=== नल' होना चाहिए, गया और इसके बजाय isset का उपयोग करने के लिए मेरा उत्तर बदल दिया, फिर वापस आया यह देखने के लिए कि आपने अपनी टिप्पणी भी बदल दी है। : डी
रयान पी

आह, ड्रम! मुझे यह बिल्कुल पसंद नहीं है ... ओह ठीक है, आपके पास सब कुछ नहीं हो सकता। मुझे लगता है कि मुझे अपने डिफ़ॉल्ट तर्कों के क्रम में थोड़ा और विचार करना होगा। धन्यवाद!
वृद्धावस्था

दुर्भाग्य से, आप इस उत्तर के साथ अशक्त नहीं हो पाएंगे। यह एक बेहतर विकल्प है: $x = !array_key_exists('x',$args) ? 'default x value' : $args['x'];
फ्रैंक फोर्ट

20

यह वास्तव में संभव है:

foo( 'blah', (new ReflectionFunction('foo'))->getParameters()[1]->getDefaultValue(), 'test');

आप ऐसा करना चाहेंगे या नहीं, एक और कहानी है :)


अपडेट करें:

इस समाधान से बचने के कारण हैं:

  • यह (यकीनन) बदसूरत है
  • यह एक स्पष्ट उपरि है।
  • अन्य उत्तरों के प्रमाण के रूप में, विकल्प हैं

लेकिन यह वास्तव में उन स्थितियों में उपयोगी हो सकता है जहां:

  • आप मूल फ़ंक्शन को बदल नहीं सकते / नहीं चाहते हैं।

  • आप फ़ंक्शन को बदल सकते हैं लेकिन:

    • null(या समकक्ष) का उपयोग करना एक विकल्प नहीं है (डिएगोडीडी की टिप्पणी देखें )
    • आप या तो एक सहयोगी के साथ या साथ नहीं जाना चाहते हैं func_num_args()
    • आपका जीवन LOCs के एक जोड़े को बचाने पर निर्भर करता है

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

बेशक, यदि आप इसका उपयोग लूप में करते हैं, तो आपको पहले से डिफ़ॉल्ट मान प्राप्त करना चाहिए।


1
ऐसा न करने का क्या कारण है? बहुत आसान लगता है।
ब्रायन

10
function image(array $img)
{
    $defaults = array(
        'src'    => 'cow.png',
        'alt'    => 'milk factory',
        'height' => 100,
        'width'  => 50
    );

    $img = array_merge($defaults, $img);
    /* ... */
}

2
क्या मैं कुछ भूल रहा हूँ? यह सवाल का जवाब बिल्कुल नहीं लगता है, लेकिन इसमें 7 बदलाव हैं। शायद थोड़ा सा स्पष्टीकरण जोड़ने से मदद मिलेगी?
बीन

3
@ सीनियन: सही, एक स्पष्टीकरण बेहतर होगा, लेकिन उनकी बात यह है: चूंकि PHP में तर्कों का नाम नहीं है, इसलिए अपने एकल पैरामीटर के रूप में एक साहचर्य सरणी का उपयोग करें।
MestreLion

1
प्रश्न में दिए गए उदाहरण का उपयोग करना अधिक उपयोगी है, जैसे$defaults = [ 'x' => 'some value', 'y' => 'some other value'];
फ्रैंक फोर्ट

4

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

function foo($blah, $y = "some other value", $x = "some value")

तब आप फू को कॉल कर सकते हैं जैसे:

foo("blah", "test");

यह परिणाम होगा:

$blah = "blah";
$y = "test";
$x = "some value";

3

मुझे हाल ही में यह समस्या हुई और मुझे यह सवाल और जवाब मिला। जबकि उपरोक्त प्रश्न काम करते हैं, समस्या यह है कि वे आईडीई को डिफ़ॉल्ट मान नहीं दिखाते हैं जो इसका समर्थन करते हैं (जैसे PHPStorm)।

यहां छवि विवरण दर्ज करें

यदि आप उपयोग करते हैं nullतो आपको यह नहीं पता होगा कि यदि आप इसे खाली छोड़ देते हैं तो मूल्य क्या होगा।

जो समाधान मुझे पसंद है वह फ़ंक्शन मान में डिफ़ॉल्ट मान भी डालने के लिए है:

protected function baseItemQuery(BoolQuery $boolQuery, $limit=1000, $sort = [], $offset = 0, $remove_dead=true)
{
    if ($limit===null) $limit =1000;
    if ($sort===null) $sort = [];
    if ($offset===null) $offset = 0;
    ...

एकमात्र अंतर यह है कि मुझे यह सुनिश्चित करने की आवश्यकता है कि वे समान हैं - लेकिन मुझे लगता है कि अतिरिक्त स्पष्टता के लिए भुगतान करने के लिए एक छोटी सी कीमत है।


अपने आप पर ReflectionFunction का आंतरिक उपयोग कीमत को बचाएगा!
सब्जेक्टडेल्टा

2

आप इसे सीधे नहीं कर सकते हैं, लेकिन एक छोटा सा कोड फ़िडलिंग अनुकरण करना संभव बनाता है।

function foo($blah, $x = false, $y = false) {
  if (!$x) $x = "some value";
  if (!$y) $y = "some other value";

  // code
}

6
यह काम करेगा, लेकिन मैं nullइस उदाहरण का उपयोग करने के लिए वैचारिक रूप से तुलना करने वाला हूं false
टीआरजी

TriG की टिप्पणी में जोड़ना, falseसे एक जोखिम भरा विकल्प है null, क्योंकि php एक गैर-सख्त भाषा है। !$xकई अलग-अलग इनपुट्स के लिए सही होगा, जो प्रोग्रामर को आश्चर्यचकित कर सकता है: 0, ''। जबकि null, आप !issetएक कड़े परीक्षण के रूप में उपयोग कर सकते हैं ।
टूलमेकरसवाई

1
<?php
function info($name="George",$age=18) {
echo "$name is $age years old.<br>";
}
info();     // prints default values(number of values = 2)
info("Nick");   // changes first default argument from George to Nick
info("Mark",17);    // changes both default arguments' values

?>

1

मेरे 2 सेंट अशक्त सहवर्ती ऑपरेटर ?? (PHP 7 के बाद से)

function foo($blah, $x = null, $y = null) {
    $varX = $x ?? 'Default value X';
    $varY = $y ?? 'Default value Y';
    // ...
}

आप मेरे repl.it पर अधिक उदाहरण देख सकते हैं


0

यह मामला है, जब वस्तु बेहतर होती है - क्योंकि आप अपनी वस्तु को x और y को रखने के लिए सेट कर सकते हैं, डिफॉल्ट को सेट कर सकते हैं आदि।

सरणी के साथ दृष्टिकोण ऑब्जेक्ट बनाने के लिए निकट है (वास्तव में, ऑब्जेक्ट मापदंडों और कार्यों का गुच्छा है जो ऑब्जेक्ट पर काम करेगा, और सरणी लेने वाला फ़ंक्शन कुछ गुच्छा ओवी मापदंडों पर काम करेगा)

आमतौर पर आप अशक्त या कुछ इस तरह डिफ़ॉल्ट रूप से सेट करने के लिए हमेशा कुछ कर सकते हैं


0

आप यह भी जांच सकते हैं कि क्या आपके पास तर्क के रूप में एक खाली स्ट्रिंग है ताकि आप कॉल कर सकें जैसे:

foo('blah', "", 'non-default y value', null);

समारोह के नीचे:

function foo($blah, $x = null, $y = null, $z = null) {
    if (null === $x || "" === $x) {
        $x = "some value";
    }

    if (null === $y || "" === $y) {
        $y = "some other value";
    }

    if (null === $z || "" === $z) {
        $z = "some other value";
    }

    code here!

}

इससे कोई फर्क नहीं पड़ता कि आप भरते हैं nullया "", आपको अभी भी वही परिणाम मिलेगा।


0

व्यक्तिगत मापदंडों के बजाय फ़ंक्शन के लिए एक सरणी पास करें और अशक्त सहवर्ती ऑपरेटर (PHP 7+) का उपयोग करें।

नीचे, मैं 2 आइटम के साथ एक सरणी दे रहा हूं। फ़ंक्शन के अंदर, मैं जाँच रहा हूं कि क्या आइटम 1 के लिए मान सेट है, यदि डिफ़ॉल्ट वॉल्ट असाइन नहीं किया गया है।

$args = ['item2' => 'item2',
        'item3' => 'value3'];

    function function_name ($args) {
        isset($args['item1']) ? $args['item1'] : 'default value';
    }

आप $args['item1'] = $args['item1']??'default value'; PHP 7+ में उपयोग कर सकते हैं । अगर $ args ['item1'] शून्य है, तो default valueस्ट्रिंग $ args ['
item1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.