61

How can I call a normal (not static) class function by its name?

The below gives an error saying param 1 needs to be a valid callback. I don't want the function to be static, I want it to be a normal function, and all the examples I've seen so far had them static.

class Player
{
    public function SayHi() { print("Hi"); }
}

$player = new Player();

call_user_func($Player, 'SayHi');
5
  • read example 4 on their documentation: php.net/manual/en/function.call-user-func.php Commented May 24, 2013 at 17:02
  • I wonder that it is not complaining about the case. You are declaring "player" but calling "Player", with a capital "P". Commented May 24, 2013 at 17:05
  • @drale2k: It is complaining. "param 1 needs to be a valid callback" Commented May 24, 2013 at 17:07
  • sorry, just a typo on this site on the P vs p. @Rocket, I understand that but was wondering how I would fix it in php syntax like the answers below provided me. Commented May 24, 2013 at 17:22
  • 1
    This worked for me, and shows several methods even suggests speed differences among them: designcise.com/web/tutorial/… Commented Jun 25, 2019 at 15:37

5 Answers 5

137

The callback syntax is a little odd in PHP. What you need to do is make an array. The 1st element is the object, and the 2nd is the method.

call_user_func(array($player, 'SayHi'));

You can also do it without call_user_func:

$player->{'SayHi'}();

Or:

$method = 'SayHi';
$player->$method();
Sign up to request clarification or add additional context in comments.

3 Comments

Please is the third example identified with a particular name?
What is the second method called?
@Zack I know it might be a bit late, but for future people, this is called variable functions manual and for variables is called variables variable manual
11

You need to pass the object and method together as an array:

call_user_func(array($Player, 'SayHi'));

See callbacks, specifically:

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

Comments

5

I am giving my answer to a different question here ( PHP - Can you assign a member function to a variable? ), because it was marked as duplicate by some stackoverflow radicals, and I cannot give my answer to his question! The mentality of stackoverflow fanatics needs to stop.

btw generally this is anti pattern:

$a = 'Pl';
$b = 'aye';
$c = 'r';

$z = $a . $b . $c;

$myz = new $z();


$d = 'Say';
$e = 'Hi';

$x = $d.$e;
$myz->{$x}()

now spread out all variables across your code. You have become the anti christ.

why? because nobody can read your code any longer. Including yourself.

Better is to have the actual references in your code to the function calls you make. Not hidden in some obscure strings. No, just standard calls to the code, wrapped into a function.

Try to keep it as simple as possible. So a better solution would be this:

$x = function(){
  $player = new Player();
  $player->sayHi();
};


$x();

your IDE will find those references. $myz->{$x}() your IDE will not find and you wont be able to maintain well your code

Comments

2

I wanted to add an answer for people that have a class function that has arguments as well:

class Player{
    public function Say($what){ print($what); }
}

$player = new Player();
call_user_func_array( [ $player, 'Say' ], [ 'Hi' ] );

If you have more arguments in your function Player you can put them in the call_user_func_array's second array:

class Player{
    public function Say($what,$end){ print($what.$end); }
}

$player = new Player();
call_user_func_array( [ $player, 'Say' ], [ 'Hi','gh' ] );

Comments

-1

You are anyway creating an object of the class, so you can use object to call its function.

$player = new Player();
$player->SayHi();

or use callback

$player = new Player();
call_user_func(array($player, 'SayHi'));

1 Comment

That was just an example. I need to store the objects and their functions as callbacks, that will be fired from another system, but I didn't want to type that code out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.