我对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");   

我满心期待这样的东西能起作用。但它完全不像我想象的那样。似乎无论我做什么,每次调用函数时,我都必须输入默认参数。我肯定遗漏了一些明显的东西。


当前回答

在PHP 8中,我们可以使用命名参数来解决这个问题。

所以我们可以解决这个问题的原始海报所描述的问题:

如果我想使用$x的默认参数,并为$y设置一个不同的参数呢?

:

foo(blah: "blah", y: "test");

参考:https://wiki.php.net/rfc/named_params(特别是“跳过默认值”部分)

其他回答

你也可以检查你是否有一个空字符串作为参数,这样你可以调用:

Foo ('blah', "", '非默认y值',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还是"",你仍然会得到相同的结果。

PHP 8的方法:

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

这实际上是可能的:

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

你是否想这样做是另一个故事:)


更新:

避免这种解决方案的原因是:

它(可以说)丑陋 它有一个明显的开销。 正如其他答案所证明的那样,还有其他选择

但它实际上在以下情况下很有用:

你不想/不能改变原来的函数。 你可以改变函数,但是: 使用空(或等效)不是一个选项(见DiegoDD的评论) 你既不想使用associative也不想使用func_num_args() 你的命就靠救几个人质了

关于性能,一个非常简单的测试表明,使用Reflection API获取默认参数会使函数调用变慢25倍,但仍然需要不到1微秒的时间。你应该知道你能不能接受。

当然,如果您打算在循环中使用它,则应该事先获取默认值。

您不能直接这样做,但是稍微修改一下代码就可以进行模拟。

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

  // code
}

在PHP 8中,我们可以使用命名参数来解决这个问题。

所以我们可以解决这个问题的原始海报所描述的问题:

如果我想使用$x的默认参数,并为$y设置一个不同的参数呢?

:

foo(blah: "blah", y: "test");

参考:https://wiki.php.net/rfc/named_params(特别是“跳过默认值”部分)