PHP pass function name as param then call the function?

65,092

Solution 1

I think you are looking for call_user_func.

An example from the PHP Manual:

<?php
function barber($type) {
    echo "You wanted a $type haircut, no problem";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>

Solution 2

In php this is very simple.

<?php

function here() {
  print 'here';
}


function dynamo($name) {
 $name();
}

//Will work
dynamo('here');
//Will fail
dynamo('not_here');

Solution 3

function foo($function) {
  $function(" World");
}
function bar($params) {
  echo "Hello".$params;
}

$variable = 'bar';
foo($variable);

Additionally, you can do it this way. See variable functions.

Solution 4

I know the original question asked about PHP 4.3, but now it's a few years later and I just wanted to advocate for my preferred way to do this in PHP 5.3 or higher.

PHP 5.3+ now includes support for anonymous functions (closures), so you can use some standard functional programming techniques, as in languages like JavaScript and Ruby (with a few caveats). Rewriting the call_user_func example above in "closure style" would look like this, which I find more elegant:

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

$barber('mushroom');
$barber('shave');

Obviously, this doesn't buy you much in this example - the power and flexibility comes when you pass these anonymous functions to other functions (as in the original question). So you can do something like:

$barber_cost = function($quantity) {
    return $quantity * 15;
};

$candy_shop_cost = function($quantity) {
    return $quantity * 4.50;   // It's Moonstruck chocolate, ok?
};

function get_cost($cost_fn, $quantity) {
    return $cost_fn($quantity);
}

echo '3 haircuts cost $' . get_cost($barber_cost, 3) . "\n";
echo '6 candies cost $' . get_cost($candy_shop_cost, 6) . "\n";

This could be done with call_user_func, of course, but I find this syntax much clearer, especially once namespaces and member variables get involved.

One caveat: I'll be the first to admit I don't know exactly what's going on here, but you can't always call a closure contained in a member or static variable, and possibly in some other cases. But reassigning it to a local variable will allow it to be invoked. So, for example, this will give you an error:

$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);

But this simple workaround fixes the issue:

$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);

Solution 5

You could also use call_user_func_array(). It allows you to pass an array of parameters as the second parameter so you don't have to know exactly how many variables you're passing.

Share:
65,092
JD Isaacks
Author by

JD Isaacks

Author of Learn JavaScript Next github/jisaacks twitter/jisaacks jisaacks.com

Updated on July 02, 2020

Comments

  • JD Isaacks
    JD Isaacks almost 4 years

    I need to pass a function as a parameter to another function and then call the passed function from within the function...This is probably easier for me to explain in code..I basically want to do something like this:

    function ($functionToBeCalled)
    {
       call($functionToBeCalled,additional_params);
    }
    

    Is there a way to do that.. I am using PHP 4.3.9

    Thanks!

  • Gumbo
    Gumbo about 15 years
    “bar” has to be quoted since it’s a string.
  • Greg
    Greg about 15 years
    @Jeremy DeGroot variable functions have been around forever
  • user1260501
    user1260501 about 15 years
    I forgot the quotes, thanks for pointing that out. Added them in the edit. You can do it without quotes in 5.3?
  • strager
    strager about 15 years
    You can do it without quotes in older versions of PHP. It turns the unknown symbol into a string, and issues a warning (assuming appropriate reporting) due to the behavior being depreciated (?).
  • Pim Jager
    Pim Jager about 15 years
    @tj111, if PHP comes across an unknown CONSTANT it will assume you meant a string.
  • Nux
    Nux about 10 years
    Just for reference - in PHP 5.3 passing anonymous (no-name) functions are supported (like you can in JavaScript). They are passed directly. In previous versions of PHP passing functions as a string names is supported.
  • abbood
    abbood almost 10 years
    and so what happens when barber belongs to a different class? different namespace?
  • user4951
    user4951 almost 8 years
    Can anyone confirm?
  • w411 3
    w411 3 almost 8 years
  • PiggyMacPigPig
    PiggyMacPigPig almost 6 years
    Is this really the best answer? It does not demonstrate calling the function from within the function is was passed to as a parameter.
  • PiggyMacPigPig
    PiggyMacPigPig almost 6 years
    @abbood - public function Foo($function = null) { ...somecode... return $this->$function(@params); }
  • miken32
    miken32 over 5 years
    "Look at this code" followed by a wall of text is not terribly helpful. Especially when answering a 10 year old question with 6 other answers. Explain what this code does, and how it provides a better approach than others already mentioned here.
  • epicrato
    epicrato over 5 years
    Hi @miken32! Thanks for your observation. Where you able to take a look at the comments inside the block? The reason why I believe this is helpful is because it provides an specific context where a novice developer can see the function argument working inside a Class. Do you have any recommendations?
  • Krunoslav Djakovic
    Krunoslav Djakovic almost 5 years
    This is better solution: stackoverflow.com/questions/2700433/…
  • Rohit Gupta
    Rohit Gupta almost 2 years
    miken is right. The block is too extensive, especially for a novice. People just want a quick solution first, and then if it might work for them, they may want a more detailed one.