96

I'm sure there's a very easy explanation for this. What is the difference between this:

function barber($type){
    echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");

... and this (and what are the benefits?):

function barber($type){
    echo "You wanted a $type haircut, no problem\n";
}
barber('mushroom');
barber('shave');
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
jay
  • 10,275
  • 5
  • 34
  • 52

8 Answers8

95

Always use the actual function name when you know it.

call_user_func is for calling functions whose name you don't know ahead of time but it is much less efficient since the program has to lookup the function at runtime.

Kai
  • 9,444
  • 6
  • 46
  • 61
  • Thank-you Kai. call_user_func turned out to be exactly what I needed. – jay Oct 20 '09 at 17:57
  • 44
    `call_user_func` is not necessarily needed. You can always call a function by using variable functions: `$some_func()`. `call_user_func_array` is the one that is really useful. – Ionuț G. Stan Oct 20 '09 at 17:59
  • 24
    php always needs "to lookup the function at runtime" – VolkerK Oct 20 '09 at 18:32
  • call_user_func can also use pipes! – Cymbals Apr 03 '12 at 16:05
  • @IonuțG.Stan, You cannot, because there are **nameless** (anonymous) functions. – Pacerier Oct 18 '14 at 11:51
  • you can use it where you don't know either the function name of its arguments. – Hafiz Feb 04 '15 at 13:06
  • @VolkerK, "always" is *always* wrong. It wholly depends on the PHP engine your server uses. Engines can be built to optimize `f()`, but it's a whole magnitude harder (indeed, it's close to hardly possible) to optimize `call_user_func($function_name)` – Pacerier Jun 24 '15 at 08:05
  • 4
    @Pacerier Incorrect. Anonymous functions are still in variables, i.e. `$func = function(){};`. Any possible parameter to call_user_func has to be callable, which means it contains enough data to access it directly, whether that's `$func()`, or `$obj->{$func}()`, or whatever. – Benubird Jun 14 '17 at 15:35
  • 3
    The "less efficient" is actually very little, especially since php7, it's about few ms / million calls : https://github.com/fab2s/call_user_func – fab2s Jan 05 '18 at 20:36
  • 2
    According to one [source](https://bytes.com/topic/php/answers/13084-call_user_func-vs-variable-functions), "calling a non-existing function through a variable causes a fatal error, while call_user_func() returns a warning." So that's one difference. – mbomb007 Jul 23 '20 at 15:51
33

Although you can call variable function names this way:

function printIt($str) { print($str); }

$funcname = 'printIt';
$funcname('Hello world!');

there are cases where you don't know how many arguments you're passing. Consider the following:

function someFunc() {
  $args = func_get_args();
  // do something
}

call_user_func_array('someFunc',array('one','two','three'));

It's also handy for calling static and object methods, respectively:

call_user_func(array('someClass','someFunc'),$arg);
call_user_func(array($myObj,'someFunc'),$arg);
Lucas Oman
  • 15,597
  • 2
  • 44
  • 45
  • 9
    I know this is ages old, but couldn't find articles elsewhere. Is it more advantageous to use call_user_func('customFunction') as apposed to $variableFunction() ? What are the differences? Thanks! – David Hobs Jan 18 '14 at 18:41
13

the call_user_func option is there so you can do things like:

$dynamicFunctionName = "barber";

call_user_func($dynamicFunctionName, 'mushroom');

where the dynamicFunctionName string could be more exciting and generated at run-time. You shouldn't use call_user_func unless you have to, because it is slower.

Brian Schroth
  • 2,447
  • 1
  • 15
  • 26
7

With PHP 7 you can use the nicer variable-function syntax everywhere. It works with static/instance functions, and it can take an array of parameters. More info at https://trowski.com/2015/06/20/php-callable-paradox

$ret = $callable(...$params);
mils
  • 1,878
  • 2
  • 21
  • 42
5

I imagine it is useful for calling a function that you don't know the name of in advance... Something like:

switch($value):
{
  case 7:
  $func = 'run';
  break;
  default:
  $func = 'stop';
  break;
}

call_user_func($func, 'stuff');
pivotal
  • 736
  • 6
  • 16
3

There are no benefits to call it like that, the word user mean it is for multiple user, it is useful to create modification without editing in core engine.

it used by wordpress to call user function in plugins

<?php
/* main.php */

require("core.php");
require("my_plugin.php");

the_content(); // "Hello I live in Tasikmalaya"

...

<?php
/* core.php */

$listFunc = array();
$content = "Hello I live in @@@";

function add_filter($fName, $funct)
{
    global $listFunc;
    $listFunc[$fName] = $funct;
}

function apply_filter($funct, $content)
{
    global $listFunc;
    foreach ($listFunc as $key => $value)
    {
        if ($key == $funct and is_callable($listFunc[$key]))
        {
            $content = call_user_func($listFunc[$key], $content);
        }
    }
    echo $content;
}

function the_content()
{
  global $content;
  $content = apply_filter('the_content', $content);
  echo $content;
}

....

<?php
/* my_plugin.php */

function changeMyLocation($content){
  return str_replace('@@@', 'Tasikmalaya', $content);
}

add_filter('the_content', 'changeMyLocation'); 
uingtea
  • 6,002
  • 2
  • 26
  • 40
0

in your first example you're using function name which is a string. it might come from outside or be determined on the fly. that is, you don't know what function will need to be run at the moment of the code creation.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
-2

When using namespaces, call_user_func() is the only way to run a function you don't know the name of beforehand, for example:

$function = '\Utilities\SearchTools::getCurrency';
call_user_func($function,'USA');

If all your functions were in the same namespace, then it wouldn't be such an issue, as you could use something like this:

$function = 'getCurrency';
$function('USA');

Edit: Following @Jannis saying that I'm wrong I did a little more testing, and wasn't having much luck:

<?php
namespace Foo {

    class Bar {
        public static function getBar() {
            return 'Bar';
        }
    }
    echo "<h1>Bar: ".\Foo\Bar::getBar()."</h1>";
    // outputs 'Bar: Bar'
    $function = '\Foo\Bar::getBar';
    echo "<h1>Bar: ".$function()."</h1>";
    // outputs 'Fatal error: Call to undefined function \Foo\Bar::getBar()'
    $function = '\Foo\Bar\getBar';
    echo "<h1>Bar: ".$function()."</h1>";
    // outputs 'Fatal error: Call to undefined function \foo\Bar\getBar()'
}

You can see the output results here: https://3v4l.org/iBERh it seems the second method works for PHP 7 onwards, but not PHP 5.6.

ThomasRedstone
  • 379
  • 1
  • 4
  • 13
  • 1
    . for not being true. $fn = '\Foo\Bar\getCurrency'; $fn(); – Jan Sverre Mar 22 '14 at 13:59
  • Hi @Jannis, I'm not finding that to be true, maybe you can see where I'm going wrong, I've added a more detailed example to my answer. – ThomasRedstone May 07 '14 at 13:08
  • @ThomasRedstone did you required those functions beforehand? php do not autoload functions from other files. Also what's with that small vs big letters in namespaces. Is Bar a class? then that's another usecase. – przemo_li Nov 20 '17 at 11:28
  • hi @przemo_li, this is a single file (all within the namespace), not sure what happened with the namespace name, in my defence, I wrote the answer 4 years ago, I've updated the namespace, and added in a note about PHP 7, with a link to see the actual output. I still don't know how jansverre made it work, PHP 7 didn't enter alpha until 11 Jun 2015 – ThomasRedstone Nov 20 '17 at 15:07