170

I seem to remember that in PHP there is a way to pass an array as a list of arguments for a function, dereferencing the array into the standard func($arg1, $arg2) manner. But now I'm lost on how to do it. I recall the manner of passing by reference, how to "glob" incoming parameters ... but not how to de-list the array into a list of arguments.

It may be as simple as func(&$myArgs), but I'm pretty sure that isn't it. But, sadly, the php.net manual hasn't divulged anything so far. Not that I've had to use this particular feature for the last year or so.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Robert K
  • 30,064
  • 12
  • 61
  • 79

4 Answers4

191

As has been mentioned, as of PHP 5.6+ you can (should!) use the ... token (aka "splat operator", part of the variadic functions functionality) to easily call a function with an array of arguments:

function variadic($arg1, $arg2)
{
    // Do stuff
    echo $arg1.' '.$arg2;
}

$array = ['Hello', 'World'];

// 'Splat' the $array in the function call
variadic(...$array);

// => 'Hello World'

NB: Indexed array items are mapped to arguments by their position in the array, not their keys.

As of PHP8, and thanks to named arguments, it's possible to use the named keys of an associative array with unpacking:

$array = [
    'arg2' => 'Hello',
    'arg1' => 'World'
];

variadic(...$array);

// => 'World Hello'

(Thanks to mickmackusa for this note!)

As per CarlosCarucce's comment, this form of argument unpacking is the fastest method by far in all cases. In some comparisons, it's over 5x faster than call_user_func_array.

Aside

Because I think this is really useful (though not directly related to the question): you can type-hint the splat operator parameter in your function definition to make sure all of the passed values match a specific type.

(Just remember that doing this it MUST be the last parameter you define and that it bundles all parameters passed to the function into the array.)

This is great for making sure an array contains items of a specific type:

// Define the function...
function variadic($var, SomeClass ...$items)
{
    // $items will be an array of objects of type `SomeClass`
}

// Then you can call...
variadic('Hello', new SomeClass, new SomeClass);
    
// or even splat both ways
$items = [
    new SomeClass,
    new SomeClass,
];

variadic('Hello', ...$items);
simonhamp
  • 3,078
  • 1
  • 20
  • 26
  • 7
    This has a great performance improvement over `call_user_func_array`. So if you're using php 5.6+ I would recommend this one. [Here is a test](https://gist.github.com/nikic/6390366), which was cited in the [official php wiki](https://wiki.php.net/rfc/argument_unpacking) – CarlosCarucce Aug 26 '16 at 14:38
  • 1
    A relevant side note: named parameters can be unpacked and will respect the key (rather than the element's position). [Does PHP allow named parameters so that optional arguments can be omitted from function calls?](https://stackoverflow.com/a/64997399/2943403) (see the spread technique at the end of the answer) – mickmackusa May 04 '23 at 13:50
  • Just in case you missed it like I did since I like to skim fast, the key here is the "..." in front of the array inside the call. – Maciek Semik Aug 11 '23 at 01:53
188

Note: this solution is outdated, please refer to the answer by simonhamp for newer information.

http://www.php.net/manual/en/function.call-user-func-array.php

call_user_func_array('func',$myArgs);
IMSoP
  • 89,526
  • 13
  • 117
  • 169
vartec
  • 131,205
  • 36
  • 218
  • 244
  • 52
    Argument unpacking, as it is called, will be added in PHP 5.6 (https://wiki.php.net/rfc/argument_unpacking). It will use the 'splat operator': '...'. Its syntax: `$args = [1,2,3]; function(...$args){}` – arothuis Jul 02 '14 at 00:48
  • 4
    but what if the function you wish to call is an instance method on an object, not a function name in the global space? – ahnbizcad Oct 07 '15 at 23:16
  • 6
    @ahnbizcad then you should use a `callable`, which uses the same `call_user_func_array`, only with array where first element is the object, and second is the method. For example `call_user_func_array([$object, 'method'], $myArgs);` – SteveB Nov 09 '16 at 14:40
  • This answer is good but out of date. See simonhamp's much simpler solution for modern PHP – Joseph Meadows May 08 '22 at 23:29
85

Also note that if you want to apply an instance method to an array, you need to pass the function as:

call_user_func_array(array($instance, "MethodName"), $myArgs);
Paul Calcraft
  • 923
  • 6
  • 11
Jeff Ober
  • 4,967
  • 20
  • 15
  • 4
    @understack The `$foo->bar()` example on the [linked page](http://www.php.net/manual/en/function.call-user-func-array.php) suggests that it should be `array($instance, "MethodName")`. – Paul Calcraft Oct 05 '11 at 15:21
  • 12
    Awesome, I used this to avoid duplicating constructor arguments in a child class :) `call_user_func_array(array(parent, "__construct"), func_get_args());` – Jason May 02 '12 at 22:18
11

For sake of completeness, as of PHP 5.1 this works, too:

<?php
function title($title, $name) {
    return sprintf("%s. %s\r\n", $title, $name);
}
$function = new ReflectionFunction('title');
$myArray = array('Dr', 'Phil');
echo $function->invokeArgs($myArray);  // prints "Dr. Phil"
?>

See: http://php.net/reflectionfunction.invokeargs

For methods you use ReflectionMethod::invokeArgs instead and pass the object as first parameter.

DanMan
  • 11,323
  • 4
  • 40
  • 61