传递函数的最后一个默认参数的值

时间:2018-02-09 19:54:45

标签: php

很长一段时间我都在使用php。

但有一个问题我可能不知道

就像我有一个功能如下:

function hello($param1, $param2="2", $param3="3", $param4="4")

现在无论何时我都会使用这个函数,如果我需要第4个参数那么$ param4那么我仍然需要像这样将所有空白称为空白:

hello(1, '', '', "param4");

那么还有另一种方法可以在通话中传递第1和第4个参数而不是长长的空白列表吗?

或者还有其他标准方法吗?

4 个答案:

答案 0 :(得分:5)

这个名为skipparams的RFC已被拒绝。

PHP在调用函数时没有语法糖,例如hello(1, , , "param4");hello(1, default, default, "param4");(根据RFC),用于跳过可选参数。

如果这是你自己的函数,那么你可以选择将选项传递到插件中的常见jQuery样式,如下所示:

function hello( $param1, $more_params = [] )
{
    static $default_params = [
        'param2' => '2',
        'param3' => '3',
        'param4' => '4'
    ];

    $more_params = array_merge( $default_params, $more_params );
}

现在你可以:

hello( 1, [ 'param4'=>'not 4, muahaha!' ] );

如果您的函数需要一些高级内容,例如类型提示,而不是array_merge(),则需要手动循环$more_params并强制执行类型。

答案 1 :(得分:0)

你可以做到这一点的一种潜在方式,虽然有点hacky,但在某些情况下可能会很好。

不是传递多个变量,而是传递一个数组变量,并在函数内部检查特定键是否存在。

function hello($param1, $variables = ["param2" => "2", "param3" => "3", "param4" => "4"]) {
    if(!array_key_exists("param2", $variables)) $variables['param2'] = "2";
    if(!array_key_exists("param3", $variables)) $variables['param3'] = "3";
    if(!array_key_exists("param4", $variables)) $variables['param4'] = "4";

    echo "<pre>".print_r($variables, true)."</pre>";
}

这将允许您设置&#34; param4&#34;在上面的变量中,仍然保持所有其他变量的默认值。

以这种方式调用函数:

hello("test", ["param4" => "filling in variable 4"]);

将导致输出:

Array
(
    [param4] => filling in variable 4
    [param2] => 2
    [param3] => 3
)

如果可以避免,我通常不建议这样做,但如果您绝对需要此功能,这可能对您有用。

这里的关键是你在传递的数组中有一个特别命名的索引,你可以检查函数本身内部。

答案 2 :(得分:0)

我认为答案是肯定的,不是。

不,因为没有办法以标准的方式做到这一点。

是的,因为你可以破解它。这很hacky,但它确实有效;)

示例:

function some_call($parm1, $parm2='', $parm3='', $parm4='') { ... }

和酱汁:

function some_call_4($parm1, $parm4) {
    return some_call($parm1, '', '', $parm4);
}

因此,如果你打电话给ALOT并且厌倦了输入它,你就可以解决它。

对不起,这就是我为你所做的一切。

答案 3 :(得分:0)

这是一个开销,但您可以使用ReflectionFunction创建一个类,其实例可以使用命名参数调用:

final class FunctionWithNamedParams
{
    private $func;

    public function __construct($func)
    {
        $this->func = $func;
    }

    public function __invoke($params = [])
    {
        return ($this->func)(...$this->resolveParams($params));
    }

    private function resolveParams($params)
    {
        $rf = new ReflectionFunction($this->func);

        return array_reduce(
            $rf->getParameters(),
            function ($carry, $param) use ($params) {
                if (isset($params[$param->getName()])) {
                    $carry[] = $params[$param->getName()];
                } else if ($param->isDefaultValueAvailable()) {
                    $carry[] = $param->getDefaultValue();
                } else {
                    throw new BadFunctionCallException;
                }

                return $carry;
            },  
            []
        );
    }
}

然后你可以像这样使用它:

function hello($param1, $param2 = "2", $param3 = "3", $param4 = "4")
{
    var_dump($param1, $param2, $param3, $param4);
}

$func = new FunctionWithNamedParams('hello');

$func(['param1' => '1', 'param4' => 'foo']);

这是the demo