命名PHP可选参数?

Ste*_*ini 21 php default-value

在PHP 4/5中是否可以在调用时指定一个命名的可选参数,跳过你不想指定的参数(比如在python中)?

就像是:

function foo($a,$b='', $c='') {
    // whatever
}


foo("hello", $c="bar"); // we want $b as the default, but specify $c
Run Code Online (Sandbox Code Playgroud)

谢谢

Pas*_*TIN 21

不,这是不可能的:如果你想传递第三个参数,你必须传递第二个参数.并且命名参数也是不可能的.


一个"解决方案"是只使用一个参数,一个数组,并始终传递它......但不要总是在其中定义所有内容.

例如 :

function foo($params) {
    var_dump($params);
}
Run Code Online (Sandbox Code Playgroud)

并以这种方式调用它:

foo(array(
    'a' => 'hello',
));

foo(array(
    'a' => 'hello',
    'c' => 'glop',
));

foo(array(
    'a' => 'hello',
    'test' => 'another one',
));
Run Code Online (Sandbox Code Playgroud)

会得到这个输出:

array
  'a' => string 'hello' (length=5)

array
  'a' => string 'hello' (length=5)
  'c' => string 'glop' (length=4)

array
  'a' => string 'hello' (length=5)
  'test' => string 'another one' (length=11)
Run Code Online (Sandbox Code Playgroud)

但我真的不喜欢这个解决方案:

  • 你将失去phpdoc
  • 您的IDE将无法再提供任何提示......这很糟糕

所以我只在非常具体的情况下使用它 - 对于具有大量optionnal参数的函数,例如......


mic*_*usa 9

PHP 8 于 2020 年 11 月 26 日发布,其中包含一项名为named arguments的新功能。

在这个主要版本中,“命名参数”(又名“命名参数”)为开发人员在调用本机和自定义函数时提供了一些非常酷的新技术。

这个问题中的自定义函数现在可以使用第一个参数调用(因为它没有默认值),然后只有使用命名参数传递的第三个参数,如下所示:(Demo

function foo($a, $b = '', $c = '') {
    echo $a . '&' . $b . '&' . $c;
}

foo("hello", c: "bar"); 
// output: hello&&bar
Run Code Online (Sandbox Code Playgroud)

请注意,第二个参数不需要在函数调用中声明,因为它定义了默认值——默认值在函数中自动使用。

这个新特性的部分优点在于您不需要注意命名参数的顺序——它们的声明顺序是无关紧要的。foo(c: "bar", a: "你好"); 工作原理相同。能够“跳过”声明并编写声明性参数将提高脚本的可读性。这个新功能的唯一缺点是函数调用会有些膨胀,但我(和许多其他人)认为好处超过了这种“成本”。

下面是一个本地函数的例子,它省略了limit参数,以不正常的顺序写入参数,并声明了一个引用变量。(演示

echo preg_replace(
         subject: 'Hello 7',
         pattern: '/[a-z ]/',
         count: $counted,
         replacement: ''
     )
     . " & " . $counted;
// output: H7 & 5
Run Code Online (Sandbox Code Playgroud)

关于这个新功能还有更多要说的。您甚至可以使用关联数组将命名参数传递给函数,在该函数中可以使用展开/splat 运算符来解包数据!

(*注意声明引用变量的细微差别。)(演示

$params = [
    'subject' => 'Hello 7',  // normally third parameter
    'pattern' => '/[a-z ]/', // normally first parameter
    // 'limit'               // normally fourth parameter, omitted for this demonstration; the default -1 will be used
    'count' => &$counted,    // normally fifth parameter
    //         ^-- don't forget to make it modifiable!
    'replacement' => '',     // normally second parameter
];
echo preg_replace(...$params) . " & " . $counted;
// same output as the previous snippet
Run Code Online (Sandbox Code Playgroud)

有关更多信息,这里有一些线索进一步解释了此功能和一些常见的相关错误:(我与以下站点没有从属关系)


Jon*_*Jon 6

不,PHP无法按名称传递参数.

如果你有一个带有很多参数的函数,并且所有参数都有默认值,你可以考虑让函数接受一个参数数组:

function test (array $args) {
    $defaults = array('a' => '', 'b' => '', 'c' => '');
    $args = array_merge($defaults, array_intersect_key($args, $defaults));

    list($a, $b, $c) = array_values($args);
    // an alternative to list(): extract($args);

    // you can now use $a, $b, $c       
}
Run Code Online (Sandbox Code Playgroud)

看到它在行动.