call_user_func_array

Calls a callable with its arguments supplied as an array, positional or named.

Signature
call_user_func_array(callable $callback, array $args): mixed
  • Added in PHP 4.0.4

Parameters

ParameterTypeDescription
$callbackcallableThe callable to invoke.
$argsarrayThe arguments for the callback. Integer keys are passed positionally in array order; string keys are passed as named arguments matching parameter names.

Return value

mixedThe value returned by the callback.

Errors

Throws a TypeError if callback is not callable, and an Error if a string key does not match any parameter name or an integer key follows a string key.

Changelog

  • PHP 8.0String keys in args are now interpreted as parameter names (named arguments) instead of being silently ignored.
  • PHP 8.0An invalid callback now throws a TypeError instead of raising a warning and returning false.

call_user_func_array() is the variant of call_user_func() you use when the argument list itself lives in an array: a queued job whose payload was decoded from JSON, a middleware chain forwarding whatever it was given, a test helper that replays recorded calls.

The PHP 8 change that bites

Before PHP 8, string keys in the argument array were ignored and the values passed positionally. Since PHP 8 a string key means a named argument. Code that passed an associative array by accident and got away with it now fails loudly with an Error if the key is not a real parameter name. If you want the old positional behaviour from an associative array, run it through array_values() first.

Prefer the spread operator

In modern code $callback(...$args) does the same job with less indirection, and it also understands string keys as named arguments. call_user_func_array() stays useful mainly for callables expressed as strings and for older codebases.

References

Unlike call_user_func(), this function can pass by reference, but only if the element inside the argument array was itself created as a reference.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Replaying a queued job whose handler name and argument list were stored as data
  • Forwarding an unknown argument list from a __call() magic method to a real method
  • Calling a function whose arguments were decoded from a JSON request payload
  • Applying named arguments built dynamically from a configuration array

Frequently asked questions

What is the difference between call_user_func and call_user_func_array?

call_user_func() takes arguments one by one after the callback, while call_user_func_array() takes them as a single array. Use the array form when the argument list is data you received rather than something you wrote out.

Why does call_user_func_array throw an Error with an associative array in PHP 8?

Since PHP 8.0, string keys are treated as named arguments, so a key that does not match a parameter name is an error. Pass array_values($args) if the keys were meaningless labels.

Does call_user_func_array preserve the order of the array?

Yes for integer keys: elements are passed positionally in array order, and the actual key numbers are ignored. String-keyed elements are matched by parameter name instead of position.

More examples

Wrapping any call with logging

Prints the argument count before each call, then 9 and a-b-c. The wrapper never needs to know the arity of the function it forwards to, which is the whole point of taking the arguments as an array.

Example · php
<?php
function logged(callable $fn, array $args): mixed
{
    echo 'calling with ', count($args), " argument(s)\n";
    return call_user_func_array($fn, $args);
}

echo logged('max', [3, 9, 4]), "\n";
echo logged('implode', ['-', ['a', 'b', 'c']]), "\n";

The spread operator does the same thing

All three lines produce 12, 12 and 10. The spread operator handles both positional and string-keyed arrays, so in new code it can usually replace call_user_func_array() entirely.

Example · php
<?php
function area(float $w, float $h): float { return $w * $h; }

$args = [3.0, 4.0];
echo call_user_func_array('area', $args), "\n";
echo area(...$args), "\n";

$byName = ['h' => 2.0, 'w' => 5.0];
echo area(...$byName), "\n";

Passing an argument by reference

Prints Array ( [0] => a [1] => b ). The modification survives only because $args[0] was created as a reference with &$stack; without the ampersand PHP 8 raises an Error about the argument not being passable by reference.

Example · php
<?php
function push(array &$stack, string $item): void { $stack[] = $item; }

$stack = ['a'];
$args = [&$stack, 'b'];
call_user_func_array('push', $args);

print_r($stack);

Discussion

  • Be the first to comment on this lesson.