Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've seen a few people ask a similar question. But I do need a little more clarification on this particular subject.

I have several functions that pass several arguments. I even have a few that are about 10 arguments. (didn't initially plan it, simply grew over time)

I don't have any problems looking at my source code to find out what the 7th argument is, but it does get tedious. Most of the time I know what arguments to pass, just not the position.

I had a few ideas to simplify the process for me.

a) pass 1 argument, but divide everything with some delimiter. (but that's a bad idea!, since I still need to remember the position of each.

function myfunc('data|data|data|'){
          // explode the string
}

b) pass an array with key and values, and look for the key names inside my function, and act accordingly.

function myfunc(array('arg1' => 'blah blah', 'arg2' => 'more blah')){
  // loop through the array
}

c) keep it as it is.

function myfunc($arg1,$arg2,$arg3,$arg4,$arg5........){
// yay

}

So, I'm seeking other options and better ideas for handling functions with growing argument lists.

share|improve this question
3  
what are these functions and what are these arguments? most likely it's a consequence of poor design and number of parameters can be considerable reduced. – Your Common Sense Sep 26 '11 at 18:13
While in it's current edition the question is absolutely pointless and subjective. – Your Common Sense Sep 26 '11 at 18:14
1  
Why not refactor your code and split your function into several others? Why not use objects and pass them along to other objects? Having about 10 arguments should raise a red flag of bad design. – gilden Sep 26 '11 at 18:14

9 Answers

up vote 1 down vote accepted

b) (an associative array) is by far the easiest, most adaptible (as it allows simulating default keyword arguments), and least error-prone variant.

share|improve this answer
true, it seems most adaptable, and I can see see exactly what my keywords are, leaving less guesswork. I put it to the test, and so far it's been good to me. – coffeemonitor Sep 26 '11 at 19:18

In my opinion, the best way to it is by passing in an associative array. That way you immediately see what each argument does. Just be sure to name them descriptively, not arg1 & arg2.

Another advantage an associative array, is that you don't have to care about the order in which the arguments are being passed in.

Just remember that if you use an associative array, you lose PHP's native way of assigning default values, e.g.:

function doSomething($arg1 = TRUE, $arg2 = 55) { }

So, what you have to do is create your own set of default options, and then merge your arrays:

function doSomething( $props = array() )
{
    $props = array_merge(array(
        'arg1' => TRUE,
        'arg2' => 55
    ), $props);

    // Now use the $props array
}
share|improve this answer
In the head of the foreach it should be $props and not $options – klaustopher Sep 26 '11 at 18:18
+1 for passing associative array; -1 for trying to reinvent the wheel. – zzzzBov Sep 26 '11 at 18:26
@zzzzBov - In most situations you wouldn't want array_merge_recursive. However, array_merge does the trick (as does +=), and I've updated my answer. – Joseph Silber Sep 26 '11 at 18:32
@Joseph Silber, can you give an example where you wouldn't want array_merge_recursive? – zzzzBov Sep 26 '11 at 18:57
@zzzzBov - Maybe I'm missing something, but I think that array_merge_recursive defeats the purpose. Check out my examples of array_merge_recursive and array_merge, and tell me yourself which one makes more sense. – Joseph Silber Sep 26 '11 at 20:09
show 1 more comment

go with the myfunc($options) form when you have many optional parameters that can be mixed and matched. Use array_merge_recursive with a default options array, and you'll be golden.

share|improve this answer

First, see if you can introduce paramter object. It not necesseary to replace all 7 parameters, but maybe you can lower their count.

Next, examine the function itself - why it needs so many parameters, maybe it just does to much things? Is Replace parameter with method / Replace parameter with explicit method applicable?

By the way, Refactoring is great reading!

share|improve this answer

Depending on the intention of the function, sometimes it is appropriate to pass an object.

share|improve this answer

Let's not talk about solution #1. You already say that it is bad...

I like the second idea of passing in this hash/associative array. It feels rubylike :) The thing you are doing is that you are giving up some checks that you would get for free. If you call a function and forget an argument the runtime complains and the script stops executing. In your scenario you would have to do all those checks inside your function: Are all necessary options given? Are the values the right types, etc?

I would say, the decision is up to your taste if it's just you working on the code. If others are working with you, I would ask them about their opinion. Until then, I would stick with the classic approach of having the function with 7 arguments

share|improve this answer

Associative array with keys as parameter names, order does not count (do not to forget you document which keys are expected):

function myFunc(array $args)
{
    # default values
    $args += array('arg1' => 'default1', 'arg2' => 'default2');
}

Sometimes you want to verify that you drop all unimportant keys from the input as well. A useful function for this is array_intersect_keyDocs.

share|improve this answer

check this post about creating an ellipsis in PHP.
Creating an ellipsis in PHP

share|improve this answer

function myfunc($arg1,$arg2,$arg3,$arg4,$arg5........){

With the limited information provided, I would have to say keep it as is. The reason for this is that your function signature shows that none of your arguments have default values (they are all required).

If you make it an associative array, then you remove the parser's ability to warn about ill-called functions, i.e.:

Missing argument 2 for some_function, called in [etc.]

IDEs can help with function calling assistance if you have difficulty remembering all the arguments.

Basically, if it's a required argument, it should be in the function signature.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.