Should my PHP functions accept an array of arguments or should I explicitly request arguments?
In a PHP web application I'm working on, I see functions defined in two possible ways.
Approach 1:
function myfunc($arg1, $arg2, $arg3)
Approach 2:
// where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3)
function myfunc($array_params)
When should I use one approach over another? It seems that if system requirements keep changing, and therefore the number of arguments for myfunc keep changing, approach 1 may require a lot of maintenance.
If the system is changing so often that using an indexed array is the best solution, I'd say this is the least of your worries. :-)
In general functions/methods shouldn't take too many arguments (5 plus or minus 2 being the maximum) and I'd say that you should stick to using named (and ideally type hinted) arguments. (An indexed array of arguments only really makes sense if there's a large quantity of optional data - a good example being configuration information.)
As @Pekka says, passing an array of arguments is also liable to be a pain to document and therefore for other people/yourself in 'n' months to maintain.
Update-ette...
Incidentally, the oft mentioned book Code Complete examines such issues in quite a bit of detail - it's a great tome which I'd highly recommend.
Using a params array (a surrogate for what is called "named arguments" in other languages") is great - I like to use it myself - but it has a pretty big downside: Arguments are not documentable using standard phpDoc notation that way, and consequently, your IDE won't be able to give you hints when you type in the name of a function or method.
I find using an optional array of arguments to be useful when I want to override a set of defaults in the function. It might be useful when constructing an object that has a lot of different configuration options or is just a dumb container for information. This is something I picked up mostly from the Ruby world.
An example might be if I want to configure a container for a video in my web page:
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));
Notice that the initial value of $options is an empty array, so providing it at all is optional.
Also, with this method we know that $options will always be an array, and we know those keys have defaults so we don't constantly need to check is_array()
or isset()
when referencing the argument.