我的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签名不需要更改。