Function Parameter Hell
Everyone’s used those functions with an obscene number of parameters. And everyone’s created those functions too (big time guilty here).
Like this is a function I wrote for vaCentral to process any images you upload for your airline (logo, gallery, etc)
[php]
function process_file_upload($file, $slug, $title, $ext=’PNG’, $full_size=300, $small_size=100)
{
…
}
[/php]
Now that’s just a mess. Taking a hint from Javascript and jQuery, we can instead use arrays to pass in parameters, making it sane, and more importantly, readable. So it will look something like this:
[php]
$options = array (
‘file’=>$this->params['form'][$image],
‘slug’=>$folder,
‘title’=>$image,
‘ext’=>$ext,
‘full_size’=>$large_size,
‘small_size’=>$this->small_size
);
$this->process_image_upload($options);
[/php]
Alright, that sounds better. And looks much better, and I can actually understand what’s going on. But how will we work with this? As you’ve probably noticed, default parameters are gone. Here’s the code:
[php]
// Setup our options for what we want to pass
$options = array(
‘parameter1′=>’apples’,
‘parameter3′=>’grapes’,
);
some_function($options);
function some_function($options)
{
// Now these are the defaults
$defaults = array(
‘parameter1′=>’oranges’,
‘parameter2′=>’watermelons’,
‘parameter3′=>’grapefruit’,
‘parameter4′=>”
);
/* Now we merge the two arrays, except the $options
array takes precedence */
$options = array_merge($defaults, $options);
/* extract() creates a variable with every key from the array
so we can use that variable directly, this is optional */
extract($options);
// So now we can use the variables directly
echo $parameter1; // This will echo "apples"
echo $parameter2; // This will echo "watermelons"
/* Suppose parameter4 has to be set, so we will trigger an error
You can use throw as well if it’s in a try/catch block */
if($parameter4 == ”)
{
trigger_error(‘Parameter 4 must be set to "this value" or "that value"’, E_USER_WARNING);
}
/* Or, if you assume that the $defaults set with ” are mandatory to fill out,
you can use this code */
foreach($defaults as $name=>$value)
{
if($values == ” && $options[$name] == ” || !isset($options[$name]))
{
trigger_error("{$name} is blank, must have a value", E_USER_WARNING);
}
}
}
[/php]
Now obviously this is a little more involving, but it’s not too bad, and in my opinion, it’s well worth the extra effort needed. My tipping point is functions with more than 3 parameters will get array’d options. This also requires documentation, but I don’t think that’s such a bad thing (your sanity will thank you later). You can also peek into the function’s source code to see the parameters. But this also gives you a bit more control over error messages as well, with the trigger_error, so there’s no difference from how PHP natively reports it.
Also, another advantage is adding and removing parameters. You don’t need to reorder or completely destroy things, when in the future you decide to add or remove a parameter, which makes it real handy for API type functions. Debugging and logging can also be easier, since you can dump the entire parameters array in one swoop, without having to output every single variable, one at a time. The only drawback is the lack of restrictions on a blank value, but since there is a way around it, and you’re forced to check it, IMO that’s an advantage in the end, especially since my motto is to never trust any data coming into the system, especially in an API.