是否可以在函数调用中跳过具有默认值的参数?

发布于 2024-07-13 21:33:39 字数 219 浏览 6 评论 0原文

我有这个:

function foo($a='apple', $b='brown', $c='Capulet') {
    // do something
}

这样的事情可能吗:

foo('aardvark', <use the default, please>, 'Montague');

I have this:

function foo($a='apple', $b='brown', $c='Capulet') {
    // do something
}

Is something like this possible:

foo('aardvark', <use the default, please>, 'Montague');

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

寄离 2024-07-20 21:33:39

如果这是您的函数,您可以使用 null 作为通配符,并稍后在函数内设置默认值:

function foo($a=null, $b=null, $c=null) {
    if (is_null($a)) {
        $a = 'apple';
    }
    if (is_null($b)) {
        $b = 'brown';
    }
    if (is_null($c)) {
        $c = 'Capulet';
    }
    echo "$a, $b, $c";
}

然后您可以使用 null 跳过它们:

foo('aardvark', null, 'Montague');
// output: "aarkvark, brown, Montague"

If it’s your function, you could use null as wildcard and set the default value later inside the function:

function foo($a=null, $b=null, $c=null) {
    if (is_null($a)) {
        $a = 'apple';
    }
    if (is_null($b)) {
        $b = 'brown';
    }
    if (is_null($c)) {
        $c = 'Capulet';
    }
    echo "$a, $b, $c";
}

Then you can skip them by using null:

foo('aardvark', null, 'Montague');
// output: "aarkvark, brown, Montague"
哑剧 2024-07-20 21:33:39

如果它是您自己的函数而不是 PHP 的核心函数之一,您可以这样做:

function foo($arguments = []) {
  $defaults = [
    'an_argument' => 'a value',
    'another_argument' => 'another value',
    'third_argument' => 'yet another value!',
  ];

  $arguments = array_merge($defaults, $arguments);

  // now, do stuff!
}

foo(['another_argument' => 'not the default value!']);

If it's your own function instead of one of PHP's core, you could do:

function foo($arguments = []) {
  $defaults = [
    'an_argument' => 'a value',
    'another_argument' => 'another value',
    'third_argument' => 'yet another value!',
  ];

  $arguments = array_merge($defaults, $arguments);

  // now, do stuff!
}

foo(['another_argument' => 'not the default value!']);
懒的傷心 2024-07-20 21:33:39

发现这个,这可能仍然是正确的:

http://www.webmasterworld.com/php/3758313 .htm

简短回答:不。

长答案:是的,以上面概述的各种笨拙的方式。

Found this, which is probably still correct:

http://www.webmasterworld.com/php/3758313.htm

Short answer: no.

Long answer: yes, in various kludgey ways that are outlined in the above.

猫卆 2024-07-20 21:33:39

你几乎找到了答案,但学术/高级方法是函数柯里化,我老实说,从来没有发现有什么用处,但知道它的存在很有用。

You pretty much found the answer, but the academic/high-level approach is function currying which I honestly never found much of a use for, but is useful to know exists.

萌辣 2024-07-20 21:33:39

您可以使用一些怪癖,要么将所有参数作为数组传递,如 ceejayoz 建议,或者使用一些解析 func_get_args() 的过于复杂的代码并与默认值列表合并。 不要复制粘贴它,您必须使用对象和特征。 最后,为了能够传递各种值(不排除 null 或 false,使它们成为默认参数替换的信号),您必须声明一个虚拟的特殊类型 DefaultParam。
另一个缺点是,如果您想在任何 IDE 中获得类型提示或帮助,则必须在函数声明中复制名称和默认值。

class DefaultParam {}

trait multi_arg_functions
{
  private static function multi_arg($defaults, $list, $preserve_index = false)
  {
    $arg_keys = array_slice(array_keys($defaults), 0, count($list));

    if ($preserve_index) {
      $listed_arguments = array_slice($list, 0, count($arg_keys));
      $extras = array_slice($list, count($arg_keys), null, true);
    } else {
      $listed_arguments = array_splice($list, 0, count($arg_keys));
      $extras = &$list;
    }
    unset($list);

    $arguments = array_combine($arg_keys, $listed_arguments);
    $arguments = array_filter($arguments, function ($entry) {
      return !($entry instanceof DefaultParam); //remove entries that mean default, a special class in this case
    });
    $arguments = array_merge($defaults, $arguments);

    return [$arguments, $extras];
  }
}

class b {
  use multi_arg_functions;

  static function func1($an_argument = 'a value', $another_argument = 'another value', $third_argument = 'yet another value') { //give defaults here to get hints in an IDE
      list($args, $extras) = self::multi_arg( //note: duplicate names and defaults
          [
          'an_argument' => 'a value',
          'another_argument' => 'another value',
          'third_argument' => 'yet another value!',
          ], func_get_args());

      echo json_encode(['args' => $args, 'extras' => $extras])."\n";
  }
}

$default_param = new DefaultParam();

b::func1('value 1');
b::func1('value 2', $default_param, 'third argument');
b::func1('value 3', $default_param, 'third argument', 'fourth argument');

注意:通过使用preserve_index = true,您可以获得从原始索引开始的额外参数。

You can use some quirks, either passing all arguments as an array like ceejayoz suggests, or some overcomplicated code that parses func_get_args() and merges with a list of defaults. Not to copy-paste it, you'll have to use objects and traits. Finally, to be able to pass all kinds of values (not excluding null or false by making them a signal for default param substitution), you'll have to declare a dummy special type DefaultParam.
Another minus is that you have to duplicate the names and default values in the function declaration, if you want to get type hints or help in any IDE.

class DefaultParam {}

trait multi_arg_functions
{
  private static function multi_arg($defaults, $list, $preserve_index = false)
  {
    $arg_keys = array_slice(array_keys($defaults), 0, count($list));

    if ($preserve_index) {
      $listed_arguments = array_slice($list, 0, count($arg_keys));
      $extras = array_slice($list, count($arg_keys), null, true);
    } else {
      $listed_arguments = array_splice($list, 0, count($arg_keys));
      $extras = &$list;
    }
    unset($list);

    $arguments = array_combine($arg_keys, $listed_arguments);
    $arguments = array_filter($arguments, function ($entry) {
      return !($entry instanceof DefaultParam); //remove entries that mean default, a special class in this case
    });
    $arguments = array_merge($defaults, $arguments);

    return [$arguments, $extras];
  }
}

class b {
  use multi_arg_functions;

  static function func1($an_argument = 'a value', $another_argument = 'another value', $third_argument = 'yet another value') { //give defaults here to get hints in an IDE
      list($args, $extras) = self::multi_arg( //note: duplicate names and defaults
          [
          'an_argument' => 'a value',
          'another_argument' => 'another value',
          'third_argument' => 'yet another value!',
          ], func_get_args());

      echo json_encode(['args' => $args, 'extras' => $extras])."\n";
  }
}

$default_param = new DefaultParam();

b::func1('value 1');
b::func1('value 2', $default_param, 'third argument');
b::func1('value 3', $default_param, 'third argument', 'fourth argument');

Note: by using preserve_index = true you get the extra arguments to start from their original index.

锦上情书 2024-07-20 21:33:39

从 PHP 8 开始,使用 命名参数

function foo($a='apple', $b='brown', $c='Capulet') {
  // do something
}
foo('apple', c:'Montague');

这可以让您绕过尽可能多的参数想要,允许它们采用默认值。 这对于冗长的函数很有帮助,例如 setcookie< /a>:

setcookie('macadamia', httponly:true); // skips over 5 parameters

请注意,命名参数要求传递所有非可选参数。 这些可以按位置传递(正如我在这里所做的那样,上面没有名称)或按任何顺序使用名称。

As of PHP 8, use named parameters:

function foo($a='apple', $b='brown', $c='Capulet') {
  // do something
}
foo('apple', c:'Montague');

This let's you bypass as many parameters as you want, allowing them to take on their default value. This is helpful in long-winded functions like setcookie:

setcookie('macadamia', httponly:true); // skips over 5 parameters

Note that named parameters require all non-optional parameters to be passed. These may be passed positionally (as I've done here, no names on them) or with names in any order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文