我的PHP函数应该接受一系列参数还是应该明确地请求参数?

在我正在开发的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可能需要大量的维护。

如果系统经常变化,那么使用索引数组是最好的解决scheme,我认为这是您最担心的问题。 🙂

在一般的函数/方法不应该占用太多的参数(5加2减去最大),我会说,你应该坚持使用命名(和理想的types暗示 )参数。 (如果有大量的可选数据,索引的参数数组才是真正有意义的 – 一个很好的例子就是configuration信息。)

正如@皮卡所说,通过一系列的论证也可能是一个痛苦的文件,因此对于其他人/你自己来维护。

更新ETTE …

顺便说一句,经典的“ Code Complete”一书详细地介绍了这些问题 – 这是我强烈推荐的一个很好的方法。

使用params数组(其他语言中称为“命名参数”的替代品)非常棒 – 我喜欢自己使用它 – 但它有一个很大的缺点:参数不能用这种标准的phpDoc表示法来logging,而且因此,当您input函数或方法的名称时,您的IDE将无法给出提示。

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

一个例子可能是如果我想在我的网页中configuration一个video容器:

 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的初始值是一个空数组,所以完全可以select。

而且,通过这个方法,我们知道$ options将总是一个数组,我们知道这些键有默认值,所以当引用参数时,我们并不总是需要检查is_array()isset()

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

每种方式都有优点和缺点。

  • 如果这是一个不太可能改变的简单函数,并且只有几个论点,那么我会明确地陈述它们。

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

例如,当我select一个数组作为参数时,如果我有一个创build表单字段的函数。 我可能想要的可能的论据:

  • types
  • ID
  • 样式
  • 选项
  • 是必须的

我可能只需要通过一些这些。 例如,如果一个字段是type = text,我不需要选项。 我可能并不总是需要一个类或一个默认值。 这样一来,传递几个参数组合就变得容易了,而且没有带有参数的函数签名,并且一直传递null。 另外,当HTML5从现在开始成为许多年的标准时,我可能需要添加其他可能的参数,例如打开或closures自动完成。

如果你传入的参数可以合理地分组在一起,那么你可以考虑使用一个参数对象( Refactoring ,Martin Fowler,p295),这样,如果你需要添加更多的参数,你可以添加更多的字段到你的参数类和它不会破坏现有的方法。

我知道这是一个旧post,但我想分享我的方法。 如果variables在逻辑上连接在一个types中,则可以将它们组合到一个类中,并将它们的一个对象传递给该函数。 例如:

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

并致电:

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

如果需要一个新的参数,您可以将其添加到类中,而function签名不需要更改。