183

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.

4 Answers 4

214

As has been mentioned, as of PHP 5.6+ you can (should!) use the ... token (aka "splat/spread 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);
Sign up to request clarification or add additional context in comments.

3 Comments

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, which was cited in the official php wiki
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? (see the spread technique at the end of the answer)
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.
190

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);

4 Comments

Argument unpacking, as it is called, will be added in PHP 5.6 (wiki.php.net/rfc/argument_unpacking). It will use the 'splat operator': '...'. Its syntax: $args = [1,2,3]; function(...$args){}
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 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);
This answer is good but out of date. See simonhamp's much simpler solution for modern PHP
86

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);

2 Comments

@understack The $foo->bar() example on the linked page suggests that it should be array($instance, "MethodName").
Awesome, I used this to avoid duplicating constructor arguments in a child class :) call_user_func_array(array(parent, "__construct"), func_get_args());
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.

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.