কোনও কার্যক্রমে ডিফল্ট তর্কগুলি ব্যবহার করা


177

আমি পিএইচপি ফাংশনগুলির জন্য ডিফল্ট মানগুলি সম্পর্কে বিভ্রান্ত। বলুন আমার এর মত একটি ফাংশন আছে:

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

আমি যদি $ x এর জন্য ডিফল্ট আর্গুমেন্টটি ব্যবহার করতে এবং for y এর জন্য আলাদা যুক্তি সেট করতে চাই তবে কী হবে?

আমি বিভিন্ন উপায়ে পরীক্ষা-নিরীক্ষা করছি এবং আমি আরও বিভ্রান্ত হয়ে পড়ছি। উদাহরণস্বরূপ, আমি এই দুটি চেষ্টা করেছিলাম:

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

তবে এগুলির উভয়ই $ x এর জন্য সঠিক ডিফল্ট তর্ক করতে পারে না। আমি এটিকে ভেরিয়েবল নামে সেট করার চেষ্টাও করেছি।

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

আমি পুরোপুরি প্রত্যাশা করছিলাম এ জাতীয় কিছু কাজ করার জন্য। আমি যেমন আশা করি তেমন কাজ করে না। দেখে মনে হচ্ছে যে আমি যাই করি না কেন, আমি ফাংশনটি প্রতিবারই অনুরোধ করে যাই হোক না কেন, ডিফল্ট আর্গুমেন্টে টাইপ করতে হবে up এবং আমি অবশ্যই কিছু স্পষ্ট অনুপস্থিত।


68
আপনি সম্ভবত কিছু মিস করছেন না, পিএইচপি বিকাশকারীরা সম্ভবত এটি মিস করেছেন।
মট্টি ভির্ককুনেন

এটি একটি আকর্ষণীয় প্রশ্ন। আপনি যা বলেছিলেন ঠিক তেমন করার দরকার ছিল না যেহেতু আমি যখন অন্য প্রোগ্রামারদের উত্তরাধিকার সূত্রে প্রাপ্ত ফাংশনগুলি প্রসারিত করতে কেবলমাত্র ডিফল্ট আরোগুলি ব্যবহার করি যখন আমি নিশ্চিত না যে মূলটির উপর নির্ভর করে কি what আমি একটি উত্তর সম্পর্কে কৌতূহলী।
কাই কিং

3
আমি একটি সময় দেখেছি সেরা প্রশ্ন! আপনি কিছু পাস করার চেষ্টা করেছেন? foo("blah", , "test");?
মাদারার ভূত

2
নিয়মটি হ'ল ডিফল্ট আর্গুমেন্টগুলি কেবল যুক্তি অনুসরণ করতে পারে। এটি হ'ল আপনি ফু ("ব্লাহ") থাকতে পারেন এবং এক্স, ওয়াই ডিফল্ট, অথবা ফু ("ব্লাহ", "এক্সআইজেড") এবং y হ'ল ডিফল্ট।
মাউস ফুড

1
প্রত্যাশিত আচরণ. "ডিফল্ট আর্গুমেন্টের মানগুলি" বিভাগটি এতে দেখুন: php.net/manual/en/function.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 = আইসেট ($ x) নয়? ; x: 'ডিফল্ট মান'; ?
zloctb

@Zloctb এটি একটি পরিষ্কার এবং পঠনযোগ্য নাল চেক। দেখে মনে হচ্ছে এটি বিকাশকারী পছন্দ। হয় $ x = আইসেট ($ x)? ; x: 'ডিফল্ট মান'; বা $ x = is_null ($ x)? 'ডিফল্ট মান': $ x; এই সমাধান হিসাবে কাজ করবে। এটি পঠনযোগ্যতা এবং রক্ষণাবেক্ষণ সম্পর্কে একটি পছন্দ পছন্দ।
বিকাশকারী

9
কেবল ভবিষ্যতের পাঠকদের জন্য স্পষ্ট করার জন্য। প্রথম সমাধানটি অবশ্যই nullপ্যারামিটারে একটি আসল মান নির্ধারণ করা অসম্ভব করে তোলে , যেহেতু প্রতিটি সময় এটি ডিফল্ট মান নির্ধারণ করে। এমনকি যখন আপনি আসলে একটি নাল চান (যেমন $ x == "ব্যবহার_নুল" তৈরি করুন $ x = নাল) এর জন্য আপনার আর একটি বিশেষ মান রয়েছে তবে আপনি এর আক্ষরিক মান হিসাবে এমন বিশেষ মান নির্ধারণ করতে পারবেন না প্যারামিটার (এই ক্ষেত্রে, "ব্যবহার_নুল" স্ট্রিং)। তাই আপনি যখন ডিফল্ট মানটি ব্যবহার করতে চান (এবং আপনি nullএকটি বৈধ বিকল্প হতে চান ) এর জন্য একটি অনন্য, কখনই পছন্দসই "কী" ব্যবহার করার বিষয়ে নিশ্চিত
হোন

37

Functionচ্ছিক আর্গুমেন্টগুলি কেবল একটি ফাংশন কল শেষে কাজ করে। Function x উল্লেখ না করে আপনার ফাংশনে $ y এর জন্য কোনও মান নির্দিষ্ট করার কোনও উপায় নেই। কিছু ভাষা নামকৃত প্যারামিটারগুলির মাধ্যমে এটি সমর্থন করে (উদাহরণস্বরূপ ভিবি / সি #), তবে পিএইচপি নয়।

আপনি যদি আর্গুমেন্টের পরিবর্তে প্যারামিটারগুলির জন্য কোনও এসোসিয়েটিভ অ্যারে ব্যবহার করেন - তবে এটি অনুকরণ করতে পারেন ie

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ডিফল্ট মান সহ প্রতিস্থাপন করবে ।
টিম কুপার

@ টিমকুপার লল আমি আপনার প্রথম মন্তব্যের উপর ভিত্তি করে পরিবর্তন করতে গিয়েছিলাম যে এটি '=== নাল' হওয়া উচিত, গিয়েছিলাম এবং পরিবর্তে আইসেট ব্যবহারের জন্য আমার উত্তর পরিবর্তন করেছিলাম, তারপরে আপনি ফিরে এসেছিলেন আপনার মন্তব্যটিও পরিবর্তন করে দেখে। : ডি
রায়ান পি

আহ, দ্রত! আমি মোটেও পছন্দ করি না ... ওহ ভাল, আপনার সব কিছুই থাকতে পারে না। আমি মনে করি আমাকে তখন আমার ডিফল্ট যুক্তিগুলির ক্রম হিসাবে আরও কিছুটা চিন্তা করতে হবে। ধন্যবাদ!
রেনোসিস

দুর্ভাগ্যক্রমে, আপনি এই উত্তরটি শূন্য করতে পারবেন না। এটি আরও ভাল বিকল্প: $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()
    • আপনার জীবন নির্ভর করে বেশ কয়েকটি এলওসি সঞ্চয় করার উপর

কর্মক্ষমতা সম্পর্কে, একটি খুব সাধারণ পরীক্ষাটি দেখায় যে ডিফল্ট পরামিতিগুলি পেতে রিফ্লেকশন এপিআই ব্যবহার করে ফাংশন কলটি 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 টি upvotes রয়েছে। সম্ভবত ব্যাখ্যা একটি বিট যোগ সাহায্য করবে?
শান দ্য বিন

3
@ সিনিথবিয়ান: সত্য, ব্যাখ্যাটি আরও ভাল হবে তবে তার বক্তব্যটি হ'ল পিএইচপি যেহেতু যুক্তিগুলির নাম দেয় না, তাই তার একক প্যারামিটার হিসাবে কোনও এসোসিয়েটিভ অ্যারে ব্যবহার করে।
MestreLion

1
প্রশ্নে প্রদত্ত উদাহরণটি ব্যবহার করা আরও সহায়ক, যেমন$defaults = [ 'x' => 'some value', 'y' => 'some other value'];
ফ্রাঙ্ক ফোর্টাল

4

এটি করার একমাত্র উপায় আমি প্যারামিটার বাদ দিয়ে। প্যারামিটার বাদ একমাত্র উপায় পরামিতি তালিকা নতুন করে সাজানো যাতে আপনি বর্জন করতে চান পরামিতি পর যে আপনি হয় আছে সেটে। উদাহরণ স্বরূপ:

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

তারপরে আপনি foo কে এভাবে কল করতে পারেন:

foo("blah", "test");

এর ফলস্বরূপ:

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

3

আমি সম্প্রতি এই সমস্যাটি পেয়েছি এবং এই প্রশ্ন এবং উত্তরগুলি পেয়েছি। উপরের প্রশ্নগুলি কাজ করার সময়, সমস্যাটি হ'ল তারা এটি সমর্থন করে এমন আইডিইগুলিকে ডিফল্ট মানগুলি প্রদর্শন করে না (যেমন পিএইচপিএসটারম)।

এখানে চিত্র বর্ণনা লিখুন

আপনি যদি এটি ব্যবহার করেন 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;
    ...

পার্থক্যটি হ'ল আমার নিশ্চিত হওয়া উচিত যে সেগুলি একই - তবে আমি মনে করি অতিরিক্ত স্পষ্টতার জন্য মূল্য দিতে এটি একটি ছোট দাম price


অভ্যন্তরীণ প্রতিবিম্বের ব্যবহার নিজেই দাম বাঁচাতে পারে!
সাবজেক্টডেল্টা

2

আপনি সরাসরি এটি করতে পারবেন না, তবে একটি সামান্য কোড ফিডলিং অনুকরণ করা সম্ভব করে।

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

  // code
}

6
এটি কার্যকর হবে, তবে আমি nullএই উদাহরণটি ব্যবহার করে তুলনায় ধারণাগতভাবে আরও নিবিড় বলে মনে করি false
ট্রিগ

ট্রিগের মন্তব্যে যুক্ত করা falseতুলনায় ঝুঁকিপূর্ণ পছন্দ null, কারণ পিএইচপি একটি অ-কঠোর ভাষা। !$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 সেন্ট ??(পিএইচপি 7 সাল থেকে)

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

আপনি আমার repl.it আরও উদাহরণ পরীক্ষা করতে পারেন


0

এটি ক্ষেত্রে, যখন অবজেক্ট ভাল হয় - কারণ আপনি x এবং y ধরে রাখতে আপনার অবজেক্ট সেট আপ করতে পারেন, ডিফল্ট সেট আপ করতে পারেন etc.

অ্যারের সাথে অ্যাপ্রোচটি অবজেক্ট তৈরি করার কাছাকাছি (আসলে বস্তুটি প্যারামিটার এবং ফাংশনগুলির গুচ্ছ যা বস্তুর উপর কাজ করবে এবং ফাংশন নেওয়ার ফলে অ্যারে কিছু গুচ্ছ ডিম্বাশয়ের পরামিতিগুলির কাজ করবে)

শুদ্ধভাবে আপনি সর্বদা শূন্য বা এই জাতীয় কিছুটিকে ডিফল্ট হিসাবে সেট করতে কিছু কৌশল করতে পারেন


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

পৃথক প্যারামিটারের পরিবর্তে ফাংশনে একটি অ্যারে পাস করুন এবং নাল কোয়েলসিং অপারেটর (পিএইচপি 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'; পিএইচপি 7+ ব্যবহার করতে পারেন । যদি $ args [ 'ITEM1'] নাল তারপর default valueস্ট্রিং $ args নির্ধারিত হবে [ 'ITEM1']
Sadee
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.