358

I need to be able to call a function, but the function name is stored in a variable, is this possible? e.g:

function foo ()
{
    //code here
}

function bar ()
{
    //code here
}

$functionName = "foo";
// I need to call the function based on what is $functionName
1
  • I know this was almost 2 years ago, but thank you for asking this. Made my life so much easier. Commented Dec 29, 2022 at 16:47

19 Answers 19

544

$functionName() or call_user_func($functionName)

If you need to provide parameters stored in another variable (in the form of array), use array unpacking operator:

$function_name = 'trim';
$parameters = ['aaabbb','b'];
echo $function_name(...$parameters); // aaa

To dynamically create an object and call its method use

$class = 'DateTime';
$method = 'format';
echo (new $class)->$method('d-m-Y');

or to call a static method

$class = 'DateTime';
$static = 'createFromFormat';
$date = $class::$static('d-m-Y', '17-08-2023');
Sign up to request clarification or add additional context in comments.

10 Comments

If you need to call an object's function whose name is in a variable do this: call_user_func( array($obj,$func), $params )
Also see my answer below if you are dealing with classes and methods. I didn't expect what I found.
How could I void function definition error if the the function was not defined? Does if($functionName) enough?
@sємsєм: You should use the is_callable function. It will check if a variable contains something that can be called as a function (be it the name of a function, an array containing an object instance and a function name, or an anonymous function/closure)
@Pacerier: Provide the classname as first element of the array: call_user_func(array('ClassName', 'method'), $args)
|
163

My favorite version is the inline version:

${"variableName"} = 12;

$className->{"propertyName"};
$className->{"methodName"}();

StaticClass::${"propertyName"};
StaticClass::{"methodName"}();

You can place variables or expressions inside the brackets too!

4 Comments

@marcioAlmada : post a comment instead of editing others' answers in this manner; it adds confusion - it's not clear who said what [to the curious: see revisions for explanations]
Ok @kryger. Line 2 {"functionName"}(); is not legal and will throw a syntax error.
Thank you guys, for the replies, it indeed throws an error, even in php 5.4, so that syntax only works with object methods. Edited the post.
Note that generally you can combine Variable functions and Variable variables so you can actually do something like StaticClass::${StaticClass::$method_name}() or self::{self::$some_method}() :) seems weird, but it's useful when you want to have e.g. a variable loading function in __call :)
47

Solution: Use PHP7

Note: For a summarized version, see TL;DR at the end of the answer.

Old Methods

Update: One of the old methods explained here has been removed. Refer to other answers for explanation on other methods, it isn't covered here. By the way, if this answer doesn't help you, you should return upgrading your stuff. PHP 5.6 support has ended in January 2019 (now even PHP 7.2 and 7.3 are not being supported). See supported versions for more information.

As others mentioned, in PHP5 (and also in newer versions like PHP7) we could use variables as function names, use call_user_func() and call_user_func_array(), etc.

New Methods

As of PHP7, there are new ways introduced:

Note: Everything inside <something> brackets means one or more expressions to form something, e.g. <function_name> means expressions forming a function name.

Dynamic Function Call: Function Name On-the-fly

We can form a function name inside parentheses in just one go:

(<function_name>)(arguments);

For example:

function something(): string
{
    return "something";
}

$bar = "some_thing";

(str_replace("_", "", $bar))(); // something

// Possible, too; but generally, not recommended, because makes your
// code more complicated
(str_replace("_", "", $bar))()(); 

Note: Although removing the parentheses around str_replace() is not an error, putting parentheses makes code more readable. However, you cannot do that sometimes, e.g. while using . operator. To be consistent, I recommend you to put the parentheses always.

Dynamic Function Call: Callable Property

A useful example would be in the context of objects: If you have stored a callable in a property, you have to call it this way:

($object->{<property_name>})();

As a simple example:

// Suppose we're in a class method context
($this->eventHandler)();

Obviously, calling it as $this->eventHandler() is plain wrong: By that you mean calling a method named eventHandler.

Dynamic Method Call: Method Name On-the-fly

Just like dynamic function calls, we can do the same way with method calls, surrounded by curly braces instead of parentheses (for extra forms, navigate to TL;DR section):

$object->{<method_name>}(arguments);
$object::{<method_name>}(arguments);

See it in an example:

class Foo
{
    public function another(): string
    {
        return "something";
    }
}

$bar = "another thing";

(new Something())->{explode(" ", $bar)[0]}(); // something

Dynamic Method Call: The Array Syntax

A more elegant way added in PHP7 is the following:

[<object>, <method_name>](arguments);
[<class_name>, <method_name>](arguments); // Static calls only

As an example:

class Foo
{
    public function nonStaticCall()
    {
        echo "Non-static call";
    }
    public static function staticCall()
    {
        echo "Static call";
    }
}

$x = new Foo();

[$x, "non" . "StaticCall"](); // Non-static call
[$x, "static" . "Call"](); // Static call

Note: The benefit of using this method over the previous one is that, you don't care about the call type (i.e. whether it's static or not).

Note: If you care about performance (and micro-optimizations), don't use this method. As I tested, this method is really slower than other methods (more than 10 times).

Extra Example: Using Anonymous Classes

Making things a bit complicated, you could use a combination of anonymous classes and the features above:

$bar = "SomeThing";

echo (new class {
    public function something()
    {
        return 512;
    }
})->{strtolower($bar)}(); // 512

TL;DR (Conclusion)

Generally, in PHP7, using the following forms are all possible:

// Everything inside `<something>` brackets means one or more expressions
// to form something

// Dynamic function call via function name
(<function_name>)(arguments);

// Dynamic function call on a callable property
($object->{<property_name>})(arguments);

// Dynamic method call on an object
$object->{<method_name>}(arguments);
$object::{<method_name>}(arguments);

// Dynamic method call on a dynamically-generated object
(<object>)->{<method_name>}(arguments);
(<object>)::{<method_name>}(arguments);

// Dynamic method call, statically
ClassName::{<method_name>}(arguments);
(<class_name>)::{<method_name>}(arguments);

// Dynamic method call, array-like (no different between static
// and non-static calls
[<object>, <method_name>](arguments);

// Dynamic method call, array-like, statically
[<class_name>, <method_name>](arguments);

Special thanks to this PHP talk.

5 Comments

Nice list of expressions, also includes: (expressions)->$bar()
@Necro Thanks, I added it!
I tried this but it's not working: $class_name = 'TestController'; $fn = 'sayHello'; ($class_name)::{$fn}(). Error says: Class "TestController" not found. I don't know what I'm doing wrong...
@rhemmuuu, you must use the fully-qualified class name, i.e. along its namespaces. Consider using: use NamespaceOf\TestController; $class_name = TestController::class.
under the heading Dynamic Method Call: The Array Syntax $x = new X(); should be $x = new Foo();
24

Yes, it is possible:

function foo($msg) {
    echo $msg."<br />";
}
$var1 = "foo";
$var1("testing 1,2,3");

Source: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2

Comments

21

As already mentioned, there are a few ways to achieve this with possibly the safest method being call_user_func() or if you must you can also go down the route of $function_name(). It is possible to pass arguments using both of these methods as so

$function_name = 'foobar';

$function_name(arg1, arg2);

call_user_func_array($function_name, array(arg1, arg2));

If the function you are calling belongs to an object you can still use either of these

$object->$function_name(arg1, arg2);

call_user_func_array(array($object, $function_name), array(arg1, arg2));

However if you are going to use the $function_name() method it may be a good idea to test for the existence of the function if the name is in any way dynamic

if(method_exists($object, $function_name))
{
    $object->$function_name(arg1, arg2);
}

Comments

15

A few years late, but this is the best manner now imho:

$x = (new ReflectionFunction("foo"))->getClosure();
$x();

3 Comments

Way to OOP for me, but I gave it a +1, since nobody mentioned Reflection classes yet.
Don't understand this answer. What problem is it solving, exactly?
Not compatible with 5.x or earlier
13

In case someone else is brought here by google because they were trying to use a variable for a method within a class, the below is a code sample which will actually work. None of the above worked for my situation. The key difference is the & in the declaration of $c = & new... and &$c being passed in call_user_func.

My specific case is when implementing someone's code having to do with colors and two member methods lighten() and darken() from the csscolor.php class. For whatever reason, I wanted to have the same code be able to call lighten or darken rather than select it out with logic. This may be the result of my stubbornness to not just use if-else or to change the code calling this method.

$lightdark="lighten"; // or optionally can be darken
$color="fcc";   // a hex color
$percent=0.15;  
include_once("csscolor.php");
$c = & new CSS_Color($color);
$rtn=call_user_func( array(&$c,$lightdark),$color,$percent);

Note that trying anything with $c->{...} didn't work. Upon perusing the reader-contributed content at the bottom of php.net's page on call_user_func, I was able to piece together the above. Also, note that $params as an array didn't work for me:

// This doesn't work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);

This above attempt would give a warning about the method expecting a 2nd argument (percent).

5 Comments

what does "$c = & new CSS_Color" do? I'm talking about the amp (&). What does this & change?
@danon & is "address of" or the "reference" operator. I am instiantiating a new object of class CSS_Color and then assigning its reference (aka address) to $c. I hate repeating code, so I often use variable variable names.
I don't understand. Aren't objects passed by reference everywhere anyways? I mean, if you pass a $c to a function and change it, the original object will be affected too, right? No matter whether you used this & or not, am I right?
I tried different combinations of symbols and only while reading the user comments on php.org was I able to get working code. You'll need to start that discussion with people responsible for php's behavior.
For the second example you misread, you were looking for call_user_func_array
10

For the sake of completeness, you can also use eval():

$functionName = "foo()";
eval($functionName);

However, call_user_func() is the proper way.

3 Comments

It should be noted that eval() will allow the same behaviour but it would also allow to execute any PHP code. So the variable could be used to hijack the system. The call_user_func() does not bring such security issues.
eval is not a solution to this question.
Please don't do this because an attacker could wipe out your server entirely.
8

Dynamic function names and namespaces

Just to add a point about dynamic function names when using namespaces.

If you're using namespaces, the following won't work except if your function is in the global namespace:

namespace greetings;

function hello()
{
    // do something
}

$myvar = "hello";
$myvar(); // interpreted as "\hello();"

What to do?

You have to use call_user_func() instead:

// if hello() is in the current namespace
call_user_func(__NAMESPACE__.'\\'.$myvar);

// if hello() is in another namespace
call_user_func('mynamespace\\'.$myvar);

Comments

5

Complementing the answer of @Chris K if you want to call an object's method, you can call it using a single variable with the help of a closure:

function get_method($object, $method){
    return function() use($object, $method){
        $args = func_get_args();
        return call_user_func_array(array($object, $method), $args);           
    };
}

class test{        

    function echo_this($text){
        echo $text;
    }
}

$test = new test();
$echo = get_method($test, 'echo_this');
$echo('Hello');  //Output is "Hello"

I posted another example here

Comments

4

Use the call_user_func function.

Comments

4

What I learnt from this question and the answers. Thanks all!

Let say I have these variables and functions:

$functionName1 = "sayHello";
$functionName2 = "sayHelloTo";
$functionName3 = "saySomethingTo";

$friend = "John";
$datas = array(
    "something"=>"how are you?",
    "to"=>"Sarah"
);

function sayHello()
{
echo "Hello!";
}

function sayHelloTo($to)
{
echo "Dear $to, hello!";
}

function saySomethingTo($something, $to)
{
echo "Dear $to, $something";
}
  1. To call function without arguments

    // Calling sayHello()
    call_user_func($functionName1); 
    

    Hello!

  2. To call function with 1 argument

    // Calling sayHelloTo("John")
    call_user_func($functionName2, $friend);
    

    Dear John, hello!

  3. To call function with 1 or more arguments This will be useful if you are dynamically calling your functions and each function have different number of arguments. This is my case that I have been looking for (and solved). call_user_func_array is the key

    // You can add your arguments
    // 1. statically by hard-code, 
    $arguments[0] = "how are you?"; // my $something
    $arguments[1] = "Sarah"; // my $to
    
    // 2. OR dynamically using foreach
    $arguments = NULL;
    foreach($datas as $data) 
    {
        $arguments[] = $data;
    }
    
    // Calling saySomethingTo("how are you?", "Sarah")
    call_user_func_array($functionName3, $arguments);
    

    Dear Sarah, how are you?

Yay bye!

Comments

4

If you were in a object context trying to call a function dynamically please try something like this code bellow:

$this->{$variable}();

Comments

3

The easiest way to call a function safely using the name stored in a variable is,

//I want to call method deploy that is stored in functionname 
$functionname = 'deploy';

$retVal = {$functionname}('parameters');

I have used like below to create migration tables in Laravel dynamically,

foreach(App\Test::$columns as $name => $column){
        $table->{$column[0]}($name);
}

Comments

2

Following code can help to write dynamic function in PHP. now the function name can be dynamically change by variable '$current_page'.

$current_page = 'home_page';
$function = @${$current_page . '_page_versions'};
$function = function() {
    echo 'current page';
};
$function();

1 Comment

Anonymous functions (i.e. dynamic functions) differ from variable functions (i.e. calling functions dynamically). Also, you are replacing $function variable without any reasons.
1

Considering some of the excellent answers given here, sometimes you need to be precise. For example.

  1. if a function has a return value eg (boolean,array,string,int,float e.t.c).
  2. if the function has no return value check
  3. if the function exists

Let's look at its credit to some of the answers given.

Class Cars{
        function carMake(){
        return 'Toyota';
        }
        function carMakeYear(){
        return 2020;
        }
        function estimatedPriceInDollar{
        return 1500.89;
        }
        function colorList(){
        return array("Black","Gold","Silver","Blue");
        }
        function carUsage(){
        return array("Private","Commercial","Government");
        }
    function getCar(){
    echo "Toyota Venza 2020 model private estimated price is 1500 USD";
    }
 }

We want to check if method exists and call it dynamically.

$method = "color List";
        $class = new Cars();
        //If the function have return value;
        $arrayColor = method_exists($class, str_replace(' ', "", $method)) ? call_user_func(array($this, $obj)) : [];
        //If the function have no return value e.g echo,die,print e.t.c
     $method = "get Car";
        if(method_exists($class, str_replace(' ', "", $method))){
        call_user_func(array($class, $method))
        }

Thanks

1 Comment

I don't see what value this answer adds to this thread. Please explain the context of $this in your example and the variable $obj for the method name. I think we know what you intend there ($class and reassignment of $method) but that's not what you said. Also, please fix your formatting. I would do it but not if you're going to modify the code. Thx.
0

This is a very old threat but it is very useful today, and this should go as a comment to @MAChitgarha answer, but I can't write one, and I think it is important to add. For some might not be so obvious.

If you are inside a Namespace and you are trying one of his methods like:

// Dynamic method call on a dynamically-generated object
(<object>)->{<method_name>}(arguments);
(<object>)::{<method_name>}(arguments);

And you get an error message saying 'Class not found', it is because you MUST specify the Namespace. So you should do something like:

// Specify the Namespace with '\\' instead of '\':
('COOL\\NAMEPSACE\\'. $object)->{$method_name}(arguments); // non-static
// Or by using the __NAMESPACE__ constant:
(__NAMESPACE__ .'\\'. $object)->{$method_name}(arguments); // non-static

// It is the same for static object:
('COOL\\NAMEPSACE\\'. $object)::{$method_name}(arguments); // static
(__NAMESPACE__ .'\\'. $object)::{$method_name}(arguments); // static

You would usually just use:

COOL\NAMEPSACE\object->method_name(arguments); // non-static
COOL\NAMEPSACE\object::method_name(arguments); // static
// Notice the usage of '\' instead of '\\':

// Or if you are inside the Namespace you would simply skip the Namespace:
object->method_name(arguments); // non-static
object::method_name(arguments); // static
// And PHP applies the Namespace for you, but when using dynamic generated classes you MUST specify the Namespace

@Jivan gives a hint to this in his answer:

// if hello() is in the current namespace
call_user_func(__NAMESPACE__.'\\'.$myvar);

// if hello() is in another namespace
call_user_func('mynamespace\\'.$myvar);

But it might not be obvious at first sight.

All credit to original authors of the answer, I just wanted to point out the detail.

Comments

0

PHP 8.1.0: Store as first class callable instead of string

An alternative approach is, instead of storing the function name in a string or in an array (like what we can do from PHP 7.0), to store the callable in the new elegant way: First class callables

You can use it for normal function calls, static and non-static methods, and even object callable properties:

$function = function_name(...);
$method = $object->method(...);
$staticMethod = Class::method(...);
$callableProperty = ($object->property)(...);

This is way cleaner than the previous PHP 7.0 methods . You can also do all the dynamic things I've mentioned in the previous answer, like the followings:

$staticMethod = $className::$methodName(...);
$callableProperty = ($object->$propertyName)(...);

In short, the rule is, suppose you want to call the function the way you do, just put three dots instead of the actual arguments and you'll have the callable in your hand.

2 Comments

Incidentally, the question is "How to call a function from a string stored in a variable?"
I know, and I've edited it. I wanted to show an alternative to storing callables in strings, which is trivial for normal functions, but might not be for methods. Isn't it relevant? Should it be a comment instead?
-5

One unconventional approach, that came to my mind is, unless you are generating the whole code through some super ultra autonomous AI which writes itself, there are high chances that the functions which you want to "dynamically" call, are already defined in your code base. So why not just check for the string and do the infamous ifelse dance to summon the ...you get my point.

eg.

if($functionName == 'foo'){
  foo();
} else if($functionName == 'bar'){
  bar();
}

Even switch-case can be used if you don't like the bland taste of ifelse ladder.

I understand that there are cases where the "dynamically calling the function" would be an absolute necessity (Like some recursive logic which modifies itself). But most of the everyday trivial use-cases can just be dodged.

It weeds out a lot of uncertainty from your application, while giving you a chance to execute a fallback function if the string doesn't match any of the available functions' definition. IMHO.

3 Comments

If the value of the variable is already the name of the function why do the extra work? also it would be good to get solid feedback to see if the function exists by php before you run it: if (method_exists($functionName)) $functionName(); else //exception or handle
Yup your point is valid, but since the function name is dynamic, in your logic any string that comes shall be executed if a function by that name exists, irrespective of if that function is relevant in current situation or not. My approach makes sure that only a certain bunch of functions can be executed else an error can be thrown. It can be simplified by arrays and as such.
@MohdAbdulMujib, so then validating it using in_array() or even regex is a better approach IMO.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.