call_user_func
Calls a callable given by name, array or closure and returns whatever it returns.
call_user_func(callable $callback, mixed ...$args): mixed- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$callback | callable | The callable to invoke: a function-name string, a [$object, 'method'] or ['Class', 'staticMethod'] array, a 'Class::staticMethod' string, a Closure, or any object implementing __invoke(). |
$argsoptional | mixed | Zero or more values passed on to the callback as positional arguments. Variadic. |
Return value
mixedThe value returned by the callback.
Errors
Throws a TypeError if callback is not a valid callable. Anything thrown by the callback itself propagates to the caller unchanged.
Changelog
- PHP 8.0An invalid callback now throws a TypeError. Previously a warning was raised and false returned.
call_user_func() runs a callable that was chosen at runtime. Reach for it when the target is stored in data rather than written into the source: an event system holding listeners in an array, a router mapping a path to a controller action, a validation library where each rule is a closure, a plugin API that lets third parties register a formatter.
Direct invocation is usually better
Since PHP 7, any callable held in a variable can be called directly with $callback($a, $b), and since PHP 8.1 you can build one with first-class callable syntax such as strlen(...) or $obj->method(...). The direct form is faster, keeps by-reference parameters working, and is understood by IDEs and static analysers. Treat call_user_func() as the fallback for the cases the direct form cannot express, such as a string like 'Class::method' that you want the engine to resolve for you.
What trips people up
Arguments are always passed by value. A callback declaring &$ref will not receive a reference through call_user_func(). Also, if you need to spread an array of arguments, $callback(...$args) or call_user_func_array() is the tool, not repeated positional arguments.
Example
When to use it
- Dispatching registered event listeners stored in an array of callables
- Invoking a controller action named by a route table entry
- Running user-supplied formatter or validator closures in a plugin API
- Calling a method whose name was assembled from configuration at runtime
Frequently asked questions
What is the difference between call_user_func and calling $callback() directly?
They do the same thing, but the direct call $callback($a, $b) is faster and supports by-reference parameters, which call_user_func() does not. Use the direct form unless you specifically need the engine to resolve a string like 'Class::method'.
Can call_user_func pass arguments by reference?
No. Arguments are always copied, so a callback declaring &$param cannot change the caller's variable. Use call_user_func_array() with a reference stored in the argument array, or call the callable directly.
What happens if the callback does not exist?
PHP 8 throws a TypeError before the call is attempted, because the callable type check happens during argument parsing. Guard with is_callable() or function_exists() if the name comes from untrusted input.
More examples
Every callable form
The three lines print ARRAY FORM, STRING FORM and mrof ecnatsni. The same function accepts a class/method array, a Class::method string, and an [$object, 'method'] pair, which is why it is convenient for callbacks read from configuration.
<?php
class Formatter
{
public static function upper(string $s): string { return strtoupper($s); }
public function reverse(string $s): string { return strrev($s); }
}
echo call_user_func(['Formatter', 'upper'], 'array form'), "\n";
echo call_user_func('Formatter::upper', 'string form'), "\n";
echo call_user_func([new Formatter(), 'reverse'], 'instance form'), "\n";A minimal event dispatcher
Both listeners fire in registration order and receive the same argument, printing the two messages followed by 'handlers run: 2'. This is the pattern call_user_func() exists for: the code doing the calling has no idea what was registered.
<?php
$listeners = [];
$listeners['order.paid'][] = fn(int $id) => print("invoice generated for #$id\n");
$listeners['order.paid'][] = fn(int $id) => print("receipt emailed for #$id\n");
foreach ($listeners['order.paid'] as $listener) {
call_user_func($listener, 42);
}
echo 'handlers run: ', count($listeners['order.paid']), "\n";Invokable objects and first-class callables
Prints 21, 6 and 6. An object with __invoke() counts as a callable, and PHP 8.1's strlen(...) syntax produces a Closure. The last two lines show that the direct call $len(...) is equivalent to routing it through call_user_func().
<?php
final class Multiplier
{
public function __construct(private int $factor) {}
public function __invoke(int $n): int { return $n * $this->factor; }
}
$triple = new Multiplier(3);
echo call_user_func($triple, 7), "\n";
$len = strlen(...);
echo call_user_func($len, 'abcdef'), "\n";
echo $len('abcdef'), "\n";
Discussion