126

I have a PHP function that takes a variable number of arguments (using func_num_args() and func_get_args()), but the number of arguments I want to pass the function depends on the length of an array. Is there a way to call a PHP function with a variable number of arguments?

1

11 Answers 11

136

If you have your arguments in an array, you might be interested by the call_user_func_array function.

If the number of arguments you want to pass depends on the length of an array, it probably means you can pack them into an array themselves -- and use that one for the second parameter of call_user_func_array.

Elements of that array you pass will then be received by your function as distinct parameters.


For instance, if you have this function :

function test() {
  var_dump(func_num_args());
  var_dump(func_get_args());
}

You can pack your parameters into an array, like this :

$params = array(
  10,
  'glop',
  'test',
);

And, then, call the function :

call_user_func_array('test', $params);

This code will the output :

int 3

array
  0 => int 10
  1 => string 'glop' (length=4)
  2 => string 'test' (length=4)

ie, 3 parameters ; exactly like iof the function was called this way :

test(10, 'glop', 'test');
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, thank you. call_user_func_array() is exactly the function I was looking for.
Is it possible to use call_user_func_array() with an object method call?
@nohat : you're welcome :-) ;; about using a method of an object : yes, you can, using something like array($obj, 'methodName') as first parameter ;; actually, you can pass any "callback" you want to that function. For more informations about callbacks, see php.net/callback#language.types.callback
64

This is now possible with PHP 5.6.x, using the ... operator (also known as splat operator in some languages):

Example:

function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
    foreach ( $intervals as $interval ) {
        $dt->add( $interval );
    }
    return $dt;
}

addDateIntervaslToDateTime( new DateTime, new DateInterval( 'P1D' ), 
        new DateInterval( 'P4D' ), new DateInterval( 'P10D' ) );

1 Comment

The typed variable arguments list is a feature introduced in PHP 7.
52

In a new Php 5.6, you can use ... operator instead of using func_get_args().

So, using this, you can get all the parameters you pass:

function manyVars(...$params) {
   var_dump($params);
}

2 Comments

More info here: php.net/manual/en/…
From @fracz link, OP is trying to create a "variadic function."
52

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) { /**/ }

Comments

11

For those looking for a way to do this with $object->method:

call_user_func_array(array($object, 'method_name'), $array);

I was successful with this in a construct function that calls a variable method_name with variable parameters.

2 Comments

You can also use $object->method_name(...$array);
Going further, if you want to pass by reference, use $object->method_name(&...$args);
5

You can just call it.

function test(){        
     print_r(func_get_args());
}

test("blah");
test("blah","blah");

Output:

Array ( [0] => blah ) Array ( [0] => blah [1] => blah )

4 Comments

If I understand the OP correctly, the problem is not receiving the parameters, but calling the function with a variable number of parameters.
I didn't understanding the OP correctly, then. An array would definitely be the way to go, then. Then again, he could just pass the array directly into test(), no?
Passing an array might be a solution too, indeed -- If I understood correctly ^^
Old question but fyi, an array works fine but passing actual arguments allows you to use PHP's default values for null arguments which saves a lot of ugly checking to see if the array contains particular values.
3

I wondered, I couldn't find documentation about the possiblity of using named arguments (since PHP 8) in combination with variable arguments. Because I tried this piece of code and I was surprised, that it actually worked:

function myFunc(...$args) {
    foreach ($args as $key => $arg) {
        echo "Key: $key Arg: $arg <br>";
    }
}
echo myFunc(arg1:"foo", arg2:"bar");

Output:

Key: arg1 Arg: foo
Key: arg2 Arg: bar

In my opinion, this is pretty cool.

Comments

1

I'm surprised nobody here has mentioned simply passing and extracting an array. E.g:

function add($arr){
    extract($arr, EXTR_REFS);
    return $one+$two;
}
$one = 1;
$two = 2;
echo add(compact('one', 'two')); // 3

Of course, this does not provide argument validation. For that, anyone can use my expect function: https://gist.github.com/iautomation/8063fc78e9508ed427d5

1 Comment

extract should never be used... very bad idea to use that
0

Here is a solution using the magic method __invoke

(Available since php 5.3)

class Foo {
    public function __invoke($method=null, $args=[]){
        if($method){
            return call_user_func_array([$this, $method], $args);
        }
        return false;
    }

    public function methodName($arg1, $arg2, $arg3){

    }
}

From inside same class:

$this('methodName', ['arg1', 'arg2', 'arg3']);

From an instance of an object:

$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])

1 Comment

This is basically using call_user_func_array as stated by top voted answer in 2009. Maybe there is a point to wrapping an extra __invoke around it - but I don't see it.
0

An old question, an improved answer.

$some_array = array(
    'some-table' => array(
        'where' => array( 
            'column1 = ? and column2 = ?'
        ),
        'parameter-values' => array(1, 2),
        'html-args' => array('id' => 'id', 'name' => ''),
        'variable-arguments' => array(
            array('value-1', 'title-1'),
            array('value-2', 'title-2'),
            array('value-3', 'title-3'),
        )
    )
);

foreach ( $some_array as $table => $args ) {
    $combo = getTableCombo( 
        $table, 
        $args['where'] ?? array(),
        $args['parameter-values'] ?? array(),
        $args['html-args'] ?? array(),
        ...$args['variable-arguments'] ?? array()
    );
}

function getTableCombo( 
    string $table_name, 
    array $where = array(), 
    array $parameter_values = array(),
    array $html_args = array(), 
    array ...$custom_options
    ) {
    //some codes
}

In the above code, We could dynamically call the getTableCombo function with a variable argument named $custom_options

Comments

-1

An old question, I know, however, none of the answers here really do a good job of simply answer the question.

I just played around with php and the solution looks like this:

function myFunction($requiredArgument, $optionalArgument = "default"){
   echo $requiredArgument . $optionalArgument;
}

This function can do two things:

If its called with only the required parameter: myFunction("Hi") It will print "Hi default"

But if it is called with the optional parameter: myFunction("Hi","me") It will print "Hi me";

I hope this helps anyone who is looking for this down the road.

1 Comment

You failed to understand the question. OP was asking about arguments that he didn't have to explicitly define in the function signature - yet he can still pass values as arguments to the function. For example, the function signature doesn't have any arguments defined (optional or not), but when he requires it, OP can send 45 different values as arguments to the function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.