为了账号安全,请及时绑定邮箱和手机立即绑定

在函数中使用默认参数

/ 猿问

在函数中使用默认参数

PHP
慕田峪7331174 2019-09-21 15:27:15

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

我完全希望这样的事情能奏效。但这根本不符合我的预期。似乎不管我做什么,每次调用该函数时,无论如何我都必须最终键入默认参数。而且我必须缺少明显的东西。


查看完整描述

3 回答

?
一只萌萌小番薯

我建议按如下所示更改函数声明,以便您可以执行所需的操作:


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仍将获得其默认值。


使用此方法,传递空值意味着要覆盖一个参数的默认值,而要覆盖其后的参数的默认值。


如其他答案所述,


默认参数仅用作该函数的最后一个参数。如果要在函数定义中声明默认值,则无法省略一个参数并在其后覆盖一个参数。


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


这是另一个示例(虽然不能回答您的问题,但希望能为您提供有益的参考:


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!");

    }

}


查看完整回答
反对 回复 2019-09-21
?
慕森卡

可选参数仅在函数调用结束时起作用。如果不指定$ x,则无法在函数中指定$ y的值。某些语言通过命名参数(例如VB / C#)支持此功能,但PHP不支持。


如果对参数而不是对参数使用关联数组,则可以模拟这一点,即


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'));


查看完整回答
反对 回复 2019-09-21
?
忽然笑

实际上有可能:


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

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


更新:

避免此解决方案的原因有:


(可以说)丑陋

它有明显的开销。

作为其他答案的证明,还有其他选择

但是在以下情况下它实际上可能是有用的:


您不想/无法更改原始功能。

您可以更改功能,但:


使用null(或等效)不是一种选择(请参见DiegoDD的注释)

您既不想与他人合作,也不想与 func_num_args()

您的生活取决于保存几个LOC

关于性能,一个非常简单的测试表明,使用Reflection API获取默认参数会使函数调用慢25倍,而调用时间仍不到一微秒。您应该知道是否可以忍受。


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


查看完整回答
反对 回复 2019-09-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信