8

In Python and others, there's special syntax for variable length argument lists:

def do_something(*args):
    # do something

do_something(1, 2, 3, 4, 5, ...) # arbitrarily long list

I was reading the PHP manual, and it said this:

PHP 4 and above has support for variable-length argument lists in user-defined functions. This is really quite easy, using the func_num_args(), func_get_arg(), and func_get_args() functions.

No special syntax is required, and argument lists may still be explicitly provided with function definitions and will behave as normal.

I get the first part. You can pass as many arguments as you'd like to a function that takes no arguments, then get them as an array using func_get_args(), etc. I don't really get what the second part is saying, though.

So, my question is, is there some special syntax for variable length arguments, or some best practice that I don't know about? The approach that the manual suggests seems kludgey at best and makes your function seem like it's taking no arguments (unless I'm doing it wrong). Should I not be trying to use this language feature at all?

2
  • 7
    @Shrapnel that's kind of a PHP philosophy, isn't it? Who cares about everyone else, I'll just produce whatever? Commented Jan 2, 2011 at 15:23
  • 1
    PHP supports comments. That's enough. If you want to code, not to chatter about code. Commented Jan 2, 2011 at 15:49

6 Answers 6

18

Here is a more realistic example:

function Average()
{
    $result = 0;
    $arguments = func_get_args();

    foreach ($arguments as $argument)
    {
        $result += $argument;
    }

    return ($result / max(1, func_num_args()));
}

Average(1, 2, 3, 4, 5); // 3

This is called a variadic function.

0
10

Unlike Python's * operator or C#'s params keyword, in PHP you don't even have to specify the variable length arguments. As the second part starts off, "No special syntax is required."

As to the rest of the second paragraph: if you want to specify any required or unrelated arguments that come before the variable-length arguments, specify them in your function signature so your function can handle those. Then to get the variable-length arguments, remove the required variables from func_get_args(), like so:

function func($required) {
    // Contains all arguments that come after $required
    // as they were present at call time
    $args = array_slice(func_get_args(), 1);
}

You don't have to do this (you can still slice from func_get_args() and use its different elements accordingly), but it does make your code more self-documenting.

2
  • 1
    I was more thinking of having a name for the variable length arguments, but thank you, this is useful info. Commented Jan 2, 2011 at 15:19
  • It's a cool pattern but array_slice(func_get_args(), 1) will throw a warning in PHP 5.3 and a fatal error in 5.4 bd.php.net/manual/en/language.references.pass.php — the fix is to wrap funct_get_args() in parentheses like array_splice( (func_get_args()), 1 )
    – Mark Fox
    Commented Jan 22, 2013 at 2:06
8

Since PHP 5.6, a variable argument list can be specified with the ... operator.

function do_something($first, ...$all_the_others)
{
    var_dump($first);
    var_dump($all_the_others);
}

do_something('this goes in first', 2, 3, 4, 5);

#> string(18) "this goes in first"
#>
#> array(4) {
#>   [0]=>
#>   int(2)
#>   [1]=>
#>   int(3)
#>   [2]=>
#>   int(4)
#>   [3]=>
#>   int(5)
#> }

As you can see, the ... operator collects the variable list of arguments in an array.

If you need to pass the variable arguments to another function, the ... can still help you.

function do_something($first, ...$all_the_others)
{
    do_something_else($first, ...$all_the_others);
    // Which is translated to:
    // do_something_else('this goes in first', 2, 3, 4, 5);
}

Since PHP 7, the variable list of arguments can be forced to be all of the same type too.

function do_something($first, int ...$all_the_others) { /**/ }
2

There's no special syntax for variable length argument functions.

Simply use the func_num_args() and func_get_args() functions to get the arguments.

Example:

function callMe(){

    if(func_num_args() == 0){
        echo 'No arguments =)';
    }else{
        var_dump(func_get_args());
    }

}
0
1

The second portion is basically saying that once you start using the variable argument functions, then

function average() { ... }
function average(arg1, arg2, arg3) { ... }

work identically, just that the second version has 3 arguments explicity listed. That's all, don't try to read more into a man page than there is.

0

I usually do this to avoid kept changing function, and avoid error on argument order

function any_function($ops=array())
{
}

$ops = array('name'=>1, 'type'=>'simplexml', 'callback'=>...);
4
  • 2
    Well, you also lose the benefit of getting an error raised if the user passes the wrong arguments - or misspells one of the arguments. pros and cons.
    – troelskn
    Commented Jan 2, 2011 at 15:33
  • I would not said not true, I would prefer associate key which should more be readable to index key
    – ajreal
    Commented Jan 2, 2011 at 15:38
  • 1
    Personally, I just hate passing arrays to functions. it's too long to type all these delimiters Commented Jan 2, 2011 at 15:47
  • also auto-complete will not be aware of the parameters (for ide users)
    – beppe9000
    Commented May 13, 2019 at 16:40

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