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

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


当前回答

我知道的唯一方法是省略参数。省略参数的唯一方法是重新排列参数列表,以便要省略的参数位于必须设置的参数之后。例如:

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

然后你可以像这样调用foo:

foo("blah", "test");

这将导致:

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

其他回答

这种情况下,当对象更好-因为你可以设置你的对象来保存x和y,设置默认值等。

使用数组的方法接近于创建对象(事实上,对象是一组参数和函数,它们将在对象上工作,函数接受数组将在一些ov参数上工作)

当然,你总是可以用一些技巧来设置null或类似的默认值

另一种写法是:

function sum($args){
    $a = $args['a'] ?? 1;
    $b = $args['b'] ?? 1;
    return $a + $b;
}

echo sum(['a' => 2, 'b' => 3]); // 5 
echo sum(['a' => 2]); // 3 (2+1)
echo sum(['b' => 3]); // 4 (1+3)
echo sum([]); // 2 (1+1)

向函数传递一个数组,而不是单个参数,并使用空合并运算符(PHP 7+)。

下面,我将传递一个包含2项的数组。在函数内部,我检查item1的值是否已设置,如果没有分配默认vault。

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

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

我建议修改函数声明如下,这样你就可以做你想做的事情:

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, '非默认y值');让它像你想要的那样工作,其中第二个参数$x仍然得到它的默认值。

使用此方法,传递空值意味着当您希望覆盖后面的参数的默认值时,需要一个参数的默认值。

如其他答案所述,

默认形参仅作为函数的最后一个实参。 如果你想在函数定义中声明默认值, 没有办法省略一个参数并覆盖它后面的一个参数。

如果我有一个方法可以接受不同数量的参数,以及不同类型的参数,我通常声明的函数类似于Ryan P。

下面是另一个例子(这不能回答你的问题,但希望能提供信息:

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

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

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

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

  // code
}