4

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.

3
  • 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. Commented Sep 26, 2011 at 18:13
  • While in it's current edition the question is absolutely pointless and subjective. Commented Sep 26, 2011 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. Commented Sep 26, 2011 at 18:14

8 Answers 8

8

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
}
Sign up to request clarification or add additional context in comments.

6 Comments

In the head of the foreach it should be $props and not $options
+1 for passing associative array; -1 for trying to reinvent the wheel.
@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, can you give an example where you wouldn't want array_merge_recursive?
@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.
|
2

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

1 Comment

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.
2

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.

Comments

1

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!

Comments

0

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

Comments

0

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

Comments

0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.