As Clive has mentioned in the comments; it's because of the performance concerns.
call_user_func_array()
is widely known for its performance issues. It's even slower than its sister function call_user_func()
by 10-20% as some benchmarks revealed.
Here's the result of a benchmark ran to compare the performance of straight calls vs. dynamic calls vs. calls through call_user_func*
functions:
Dynamic function calls are slightly slower than straight calls (the former have an extra interpretive layer to determine the function to call
call_user_func()
is about 50% slower, and call_user_func_array()
is about 100% slower than a straight function call.
Static and regular method calls are roughly equivalent to function calls
call_user_func()
on method calls is typically slower than call_user_func_array()
, and the faster operation usually takes at least twice the execution time of a straight call.
— Matthew Weier O'Phinney
Paul M. Jones, another well-known PHP developer, also ran a benchmark on the exact same subject and concluded that:
So native calls to htmlentities()
are twice as fast as doing effectively the same thing via call_user_func()
with an object method, and using call_user_func_array()
is 10-20% slower than using call_user_func()
...
Clearly, PHP has to do a lot more work behind the scenes to map the variables to objects and parameters when using call_user_func_array()
.
— Paul M. Jones
Argument Unpacking
One last thing; As of PHP 5.6 and with the advent of argument unpacking operator (AKA spread, splat or scatter operator), you can safely rewrite that code to:
$instance->$method(...$args);
Quoting from the Argument Unpacking PHP RFC:
Furthermore call_user_func_array
has a rather large performance impact. If a large number of calls go through it, this can make a significant difference. For this reason, projects like Laravel and Drupal often replace particularly common call_user_func_array
calls with a switch statements.
The ...
argument unpacking syntax is about 3.5 to 4 times faster than call_user_func_args
. This solves the performance issue. Benchmark code and results.
Also, see:
Argument unpacking advantages over call_user_func_array