PHP是否允许命名参数,以便从函数调用中省略可选参数?

PHP是否允许命名参数,以便从函数调用中省略可选参数?,php,default-value,optional-parameters,named-parameters,php-8,Php,Default Value,Optional Parameters,Named Parameters,Php 8,在PHP中,调用函数/方法时是否可以指定一个命名的可选参数,而跳过不想指定的参数(如python) 比如: function foo($a, $b = '', $c = '') { // whatever } foo("hello", $c="bar"); // we want $b as the default, but specify $c 对于PHP,参数的顺序才是最重要的。您不能指定不合适的特定参数,但可以通过传递NULL跳过参数,只

在PHP中,调用函数/方法时是否可以指定一个命名的可选参数,而跳过不想指定的参数(如python)

比如:

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


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

对于PHP,参数的顺序才是最重要的。您不能指定不合适的特定参数,但可以通过传递NULL跳过参数,只要您不介意函数中的值具有NULL值

foo("hello", NULL, "bar");

对于PHP,参数的顺序才是最重要的。您不能指定不合适的特定参数,但可以通过传递NULL跳过参数,只要您不介意函数中的值具有NULL值

foo("hello", NULL, "bar");

不,这是不可能的:如果要传递第三个参数,必须传递第二个参数。和命名参数也不可能


一个“解决方案”是只使用一个参数,一个数组,并始终传递它。。。但不要总是定义其中的所有内容。 例如:

function foo($params) {
    var_dump($params);
}
并这样称呼它:(键/值数组)

将获得以下输出:

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)
但我真的不喜欢这个解决方案:

  • 你将失去phpdoc
  • 您的IDE将无法再提供任何提示。。。哪个是坏的

所以我只会在非常特殊的情况下使用它——对于具有许多可选参数的函数,例如…

不,这是不可能的:如果要传递第三个参数,就必须传递第二个参数。和命名参数也不可能


一个“解决方案”是只使用一个参数,一个数组,并始终传递它。。。但不要总是定义其中的所有内容。 例如:

function foo($params) {
    var_dump($params);
}
并这样称呼它:(键/值数组)

将获得以下输出:

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)
但我真的不喜欢这个解决方案:

  • 你将失去phpdoc
  • 您的IDE将无法再提供任何提示。。。哪个是坏的
所以我只会在非常特殊的情况下使用它——对于具有许多可选参数的函数,例如…

不,它不是

唯一可以做到这一点的方法是使用带有命名键的数组,而不是什么。

不,不是


唯一可以做到这一点的方法是使用带有命名键的数组,或者什么不带命名键的数组

class NamedArguments {

    static function init($args) {
        $assoc = reset($args);
        if (is_array($assoc)) {
            $diff = array_diff(array_keys($assoc), array_keys($args));
            if (empty($diff)) return $assoc;
            trigger_error('Invalid parameters: '.join(',',$diff), E_USER_ERROR);
        }
        return array();
    }

}

class Test {

    public static function foobar($required, $optional1 = '', $optional2 = '') {
        extract(NamedArguments::init(get_defined_vars()));
        printf("required: %s, optional1: %s, optional2: %s\n", $required, $optional1, $optional2);
    }

}

Test::foobar("required", "optional1", "optional2");
Test::foobar(array(
    'required' => 'required', 
    'optional1' => 'optional1', 
    'optional2' => 'optional2'
    ));

有些人可能会说,它并不十分漂亮,但它确实起到了作用

class NamedArguments {

    static function init($args) {
        $assoc = reset($args);
        if (is_array($assoc)) {
            $diff = array_diff(array_keys($assoc), array_keys($args));
            if (empty($diff)) return $assoc;
            trigger_error('Invalid parameters: '.join(',',$diff), E_USER_ERROR);
        }
        return array();
    }

}

class Test {

    public static function foobar($required, $optional1 = '', $optional2 = '') {
        extract(NamedArguments::init(get_defined_vars()));
        printf("required: %s, optional1: %s, optional2: %s\n", $required, $optional1, $optional2);
    }

}

Test::foobar("required", "optional1", "optional2");
Test::foobar(array(
    'required' => 'required', 
    'optional1' => 'optional1', 
    'optional2' => 'optional2'
    ));

这是我一直在用的。函数定义采用一个可选的数组参数,该参数指定可选的命名参数:

function func($arg, $options = Array()) {
  $defaults = Array('foo' => 1.0,
                    'bar' => FALSE);
  $options = array_merge($default, $options);

  // Normal function body here.  Use $options['foo'] and
  // $options['bar'] to fetch named parameter values.
  ...
}
func("xyzzy")
您通常可以在不使用任何命名参数的情况下调用:

function func($arg, $options = Array()) {
  $defaults = Array('foo' => 1.0,
                    'bar' => FALSE);
  $options = array_merge($default, $options);

  // Normal function body here.  Use $options['foo'] and
  // $options['bar'] to fetch named parameter values.
  ...
}
func("xyzzy")
要指定可选的命名参数,请在可选数组中传递它:

func("xyzzy", Array('foo' => 5.7))

这是我一直在用的。函数定义采用一个可选的数组参数,该参数指定可选的命名参数:

function func($arg, $options = Array()) {
  $defaults = Array('foo' => 1.0,
                    'bar' => FALSE);
  $options = array_merge($default, $options);

  // Normal function body here.  Use $options['foo'] and
  // $options['bar'] to fetch named parameter values.
  ...
}
func("xyzzy")
您通常可以在不使用任何命名参数的情况下调用:

function func($arg, $options = Array()) {
  $defaults = Array('foo' => 1.0,
                    'bar' => FALSE);
  $options = array_merge($default, $options);

  // Normal function body here.  Use $options['foo'] and
  // $options['bar'] to fetch named parameter values.
  ...
}
func("xyzzy")
要指定可选的命名参数,请在可选数组中传递它:

func("xyzzy", Array('foo' => 5.7))

您可以通过传递对象而不是数组来保持phpdoc和设置默认值的能力,例如

class FooOptions {
  $opt1 = 'x';
  $opt2 = 'y';
  /* etc */
};
如果您想:

function foo (FooOptions $opts) {
  ...
}

当然,您可能会为此付出额外的代价来设置FooOptions对象。不幸的是,这并不是完全免费的。

您可以通过传递对象而不是数组来保持phpdoc和设置默认值的能力,例如

class FooOptions {
  $opt1 = 'x';
  $opt2 = 'y';
  /* etc */
};
如果您想:

function foo (FooOptions $opts) {
  ...
}

当然,您可能会为此付出额外的代价来设置FooOptions对象。不幸的是,这不是完全免费的。

不,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       
}

.

否,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       
}

.

不,不太可能。你可以使用一些替代品

test(null,null,"hello")
或传递数组:

test(array('c' => "hello"));
$arr['count']=10;
$arr['type']="date";
$arr['order']="desc";
return myfunction($arr);
然后,功能可以是:

function test($array) { 
    $c = isset($array[c]) ? $array[c] : '';
}
或者在两者之间添加一个函数,但我不建议这样做:

function ctest($c) { test('','',$c); }

不,不是真的。你可以使用一些替代品

test(null,null,"hello")
或传递数组:

test(array('c' => "hello"));
$arr['count']=10;
$arr['type']="date";
$arr['order']="desc";
return myfunction($arr);
然后,功能可以是:

function test($array) { 
    $c = isset($array[c]) ? $array[c] : '';
}
或者在两者之间添加一个函数,但我不建议这样做:

function ctest($c) { test('','',$c); }
我不这么认为。。。 例如,如果您需要调用具有3个参数的函数,并且希望设置$length而不设置$start,您将被迫这样做

substr($str,0,10);
覆盖这一点的一个好方法是始终对参数使用数组

我不这么认为。。。 例如,如果您需要调用具有3个参数的函数,并且希望设置$length而不设置$start,您将被迫这样做

substr($str,0,10);

覆盖这一点的一个好方法是始终使用数组作为参数

,在非常短的时间内(有时是),通过使用反射和类型化变量。但是我想这可能不是你想要的

更好的解决方案可能是在函数自己处理函数中缺少的参数时传入3个参数

<?php  
   function test(array $params)
   {
     //Check for nulls etc etc
     $a = $params['a'];
     $b = $params['b'];
     ...etc etc
   }

简而言之,有时是的,通过使用反射和类型化变量。但是我想这可能不是你想要的

更好的解决方案可能是在函数自己处理函数中缺少的参数时传入3个参数

<?php  
   function test(array $params)
   {
     //Check for nulls etc etc
     $a = $params['a'];
     $b = $params['b'];
     ...etc etc
   }

你不能用python的方式来做。另外,您可以传递关联数组,然后按名称使用数组项:

function test ($args=array('a'=>'','b'=>'','c'=>''))
{
    // do something
}

test(array('c'=>'Hello'));
这并没有减少键入,但至少更具描述性,使参数的名称在调用中可见且可读<