【问题标题】:PHP variable length arguments?PHP可变长度参数?
【发布时间】:2011-06-02 12:19:40
【问题描述】:

在 Python 和其他语言中,可变长度参数列表有特殊的语法:

def do_something(*args):
    # do something

do_something(1, 2, 3, 4, 5, ...) # arbitrarily long list

我正在阅读 PHP 手册,它是这样说的:

PHP 4 及更高版本支持 可变长度参数列表 用户定义的函数。这真的是 很简单,使用 func_num_args(), func_get_arg() 和 func_get_args() 功能。

不需要特殊的语法,并且 参数列表可能仍然是显式的 提供函数定义和 将正常运行。

我得到了第一部分。您可以将任意数量的参数传递给不带参数的函数,然后使用 func_get_args() 等将它们作为数组获取。不过,我真的不明白第二部分在说什么。

所以,我的问题是,是否有一些可变长度参数的特殊语法,或者一些我不知道的最佳实践?手册建议的方法充其量似乎很笨拙,并且使您的函数看起来好像没有参数(除非我做错了)。我不应该尝试使用此语言功能吗?

【问题讨论】:

  • @Shrapnel 这是一种 PHP 哲学,不是吗?谁管别人,我就生产什么?
  • PHP 支持 cmets。够了。如果你想写代码,不要闲聊代码。

标签: php function variadic-functions


【解决方案1】:

这是一个更现实的例子:

function Average()
{
    $result = 0;
    $arguments = func_get_args();

    foreach ($arguments as $argument)
    {
        $result += $argument;
    }

    return ($result / max(1, func_num_args()));
}

Average(1, 2, 3, 4, 5); // 3

这称为variadic function。

【讨论】:

    【解决方案2】:

    与 Python 的 * 运算符或 C# 的 params 关键字不同,在 PHP 中,您甚至不必指定可变长度参数。在第二部分开始时,“不需要特殊语法。”

    至于第二段的其余部分:如果您想指定可变长度参数之前的任何必需或不相关的参数,请在函数签名中指定它们,以便您的函数可以处理这些。然后要获取可变长度参数,请从func_get_args() 中删除所需的变量,如下所示:

    function func($required) {
        // Contains all arguments that come after $required
        // as they were present at call time
        $args = array_slice(func_get_args(), 1);
    }
    

    您不必这样做(您仍然可以从 func_get_args() 切分并相应地使用其不同的元素),但它确实使您的代码更具自我记录性。

    【讨论】:

    • 我更想为可变长度参数命名,但谢谢,这是有用的信息。
    • 这是一个很酷的模式,但array_slice(func_get_args(), 1) 会在 PHP 5.3 中抛出警告,在 5.4 中会抛出致命错误 bd.php.net/manual/en/language.references.pass.php — 修复方法是将 funct_get_args() 括在括号中,例如 array_splice( (func_get_args()), 1 )
    【解决方案3】:

    自 PHP 5.6 起,可以使用 ... 运算符指定变量参数列表。

    function do_something($first, ...$all_the_others)
    {
        var_dump($first);
        var_dump($all_the_others);
    }
    
    do_something('this goes in first', 2, 3, 4, 5);
    
    #> string(18) "this goes in first"
    #>
    #> array(4) {
    #>   [0]=>
    #>   int(2)
    #>   [1]=>
    #>   int(3)
    #>   [2]=>
    #>   int(4)
    #>   [3]=>
    #>   int(5)
    #> }
    

    如您所见,... 运算符将变量的参数列表收集到一个数组中。

    如果您需要将变量参数传递给另一个函数,... 仍然可以帮助您。

    function do_something($first, ...$all_the_others)
    {
        do_something_else($first, ...$all_the_others);
        // Which is translated to:
        // do_something_else('this goes in first', 2, 3, 4, 5);
    }
    

    从 PHP 7 开始,参数的变量列表也可以被强制为all相同类型。

    function do_something($first, int ...$all_the_others) { /**/ }
    

    【讨论】:

      【解决方案4】:

      可变长度参数函数没有特殊语法。

      只需使用 func_num_args() 和 func_get_args() 函数来获取参数。

      例子:

      function callMe(){
      
          if(func_num_args() == 0){
              echo 'No arguments =)';
          }else{
              var_dump(func_get_args());
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        第二部分基本上是说,一旦你开始使用可变参数函数,那么

        function average() { ... }
        function average(arg1, arg2, arg3) { ... }
        

        工作原理相同,只是第二个版本明确列出了 3 个参数。就是这样,不要试图在手册页中阅读比实际内容更多的内容。

        【讨论】:

          【解决方案6】:

          我通常这样做是为了避免函数不断变化,并避免参数顺序错误

          function any_function($ops=array())
          {
          }
          
          $ops = array('name'=>1, 'type'=>'simplexml', 'callback'=>...);
          

          【讨论】:

          • 好吧,如果用户传递错误的参数或拼写错误的参数之一,您也会失去引发错误的好处。利弊。
          • 我不会说不正确,我更喜欢关联键,它应该更易读于索引键
          • 就个人而言,我只是讨厌将数组传递给函数。输入所有这些分隔符太长了
          • 自动完成也不会知道参数(对于 ide 用户)
          猜你喜欢
          • 2017-02-06
          • 2010-12-27
          • 2012-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-21
          • 2011-07-24
          • 2023-03-21
          相关资源
          最近更新 更多