我的PHP函数应该接受一个参数数组还是应该显式请求参数?

时间:2010-01-21 21:07:12

标签: php overloading

在我正在研究的PHP Web应用程序中,我看到以两种可能的方式定义函数。

方法1:

function myfunc($arg1, $arg2, $arg3)

方法2:

// where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3)
function myfunc($array_params)

我应该何时使用一种方法而不是另一种方式?似乎如果系统需求不断变化,因此myfunc的参数数量不断变化,方法1可能需要大量维护。

7 个答案:

答案 0 :(得分:29)

如果系统经常变化,使用索引阵列是最佳解决方案,我会说这是您最不担心的问题。 : - )

一般来说,函数/方法不应该使用太多的参数(5加或减2是最大值),我会说你应该坚持使用命名(和理想的type hinted)参数。 (如果存在大量可选数据,则索引的参数数组才有意义 - 一个很好的示例是配置信息。)

正如@Pekka所说,传递一系列论据也很难记录下来,因此在未来几个月内,其他人/你自己要维护。

<强>更新-ETTE ...

顺便提一下,经常提到的那本书Code Complete会详细研究这些问题 - 这是一本很棒的书,我强烈推荐。

答案 1 :(得分:17)

使用params数组(在其他语言中代替所谓的“命名参数”)很棒 - 我喜欢自己使用它 - 但它有一个非常大的缺点:使用标准的phpDoc表示法无法记录参数方式,因此,当您输入函数或方法的名称时,IDE将无法提供提示。

答案 2 :(得分:12)

当我想要覆盖函数中的一组默认值时,我发现使用可选参数数组非常有用。在构造具有许多不同配置选项的对象或者只是用于信息的哑容器时,它可能很有用。这是我主要从Ruby世界中学到的东西。

如果我想在网页中为视频配置容器,可能就是一个例子:

function buildVideoPlayer($file, $options = array())
{
  $defaults = array(
    'showAds' => true,
    'allowFullScreen' = true,
    'showPlaybar' = true
  );

 $config = array_merge($defaults, $options);

 if ($config['showAds']) { .. }
}

$this->buildVideoPlayer($url, array('showAds' => false));

请注意,$ options的初始值是一个空数组,因此提供它是可选的。

此外,使用此方法我们知道$ options将始终是一个数组,并且我们知道这些键具有默认值,因此在引用参数时我们不需要经常检查is_array()isset()

答案 3 :(得分:4)

使用第一种方法强制您的函数用户提供所需的所有参数。第二种方式,你不能确定你有你所需要的一切。我更喜欢第一种方法。

答案 4 :(得分:3)

各方面都有利弊。

  • 如果它是一个不太可能改变的简单函数,并且只有一些参数,那么我会明确说明它们。

  • 如果函数有大量参数,或者将来可能会发生很大变化,那么我会用键传递一个参数数组,并使用它。如果你有一个只需要经常传递一些参数的函数,这也会有所帮助。

如果我有一个创建表单字段的函数,我将选择一个数组而不是参数的例子。我可能想要的可能论点:

  • 输入
  • 价值
  • class
  • ID
  • style
  • 选项
  • is_required

我可能只需要通过其中一些。例如,如果一个字段是type = text,我不需要选项。我可能并不总是需要一个类或默认值。这样,传递几个参数组合更容易,没有带有ton参数的函数签名并且一直传递null。此外,当HTML 5从现在起许多年后成为标准时,我可能想要添加其他可能的参数,例如打开或关闭自动完成。

答案 5 :(得分:3)

如果您传入的参数可以逻辑分组,您可以考虑使用参数对象(重构,Martin Fowler,p295),这样如果您需要添加更多参数可以只为参数类添加更多字段,它不会破坏现有方法。

答案 6 :(得分:0)

我知道这是一篇旧帖子,但我想分享我的方法。如果变量在类型中逻辑连接,则可以将它们分组到类中,并将它们的对象传递给函数。例如:

      class user{
           public $id;
           public $name;
           public $address;
           ...
      }

并致电:

      $user = new user();
      $user->id = ...
      ...

      callFunctions($user);

如果需要新参数,您只需将其添加到类中,函数签名就不需要更改。