1
Let’s discuss: These days I took a look at the source code of a Zendframework2 class. There was an implementation of the magic method __call
. In that method there was something that caught my attention: The use of call_user_func_array
was restricted only when the method being called had more than 4 arguments. Along with it was an English commentary, which I forgot which one is, which explains why.
To confirm that this was not my (or Zendframework’s) mistake, I went to take a look at the source code of the Laravel4
and came across the same thing (but without the comment specifying why).
See the code snippet:
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
switch (count($args)) {
case 0:
return $instance->$method();
case 1:
return $instance->$method($args[0]);
case 2:
return $instance->$method($args[0], $args[1]);
case 3:
return $instance->$method($args[0], $args[1], $args[2]);
case 4:
return $instance->$method($args[0], $args[1], $args[2], $args[3]);
default:
return call_user_func_array([$instance, $method], $args);
}
}
Realize that the Laravel
only considers using call_user_func_array
if the call from __callStatic
has the passage of 5 or more arguments.
Interestingly enough, I would personally consider it useless typing code, since the call_user_func_array
would make the call of a method or function much more dynamic, but two known libraries did just the way it seemed most complex.
So I’d like to know what the reason is.
Is there a problem with loss of Performa (significantly) that induces frameworks to act in this way?
Is there a note from PHP itself that indicates this?
Note: Who wants to check the code, see here: https://github.com/illuminate/support/blob/master/Facades/Facade.php
Without any in-depth analysis I would begin by saying that this function iterates the method of the first array several times with the different values existing in the second array, that is, it maps the variables specified in the second member, in the method specified in the first member. Imagine having to map values with no need. Maybe that’s the general idea. Just like you said it’s a useless typing, calculate the total of arguments, and pass these references without making use of the
user_func_array
, the same would say for the script to map 2 parameters using this function.– Edilson
Even more, since frameworks are designed to operate as small and large applications, decreasing the time it takes for the script to execute a command and generate the response is crucial whenever possible.
– Edilson
A new information: The function
call_user_func_array
is 15 times slower than a common function call. If this is called often (as in the case of the Facade class that uses this Facade class almost in every application) it could be bad– Wallace Maxters
Exactly, as I said above, imagine having to map 2 values and take longer than necessary when you can do it directly in the intended method. Now, with about 5 arguments or more, the response time would be identical or even shorter than passing them directly in the method itself. But you wouldn’t have to write conditions for each.
– Edilson