How can I dynamically invoke a class method in PHP? The class method is not static. It appears that
call_user_func(...)
only works with static functions?
Thanks.
It works both ways - you need to use the right syntax
// Non static call
call_user_func( array( $obj, 'method' ) );
// Static calls
call_user_func( array( 'ClassName', 'method' ) );
call_user_func( 'ClassName::method' ); // (As of PHP 5.2.3)
Option 1
// invoke an instance method
$instance = new Instance();
$instanceMethod = 'bar';
$instance->$instanceMethod();
// invoke a static method
$class = 'NameOfTheClass';
$staticMethod = 'blah';
$class::$staticMethod();
Option 2
// invoke an instance method
$instance = new Instance();
call_user_func( array( $instance, 'method' ) );
// invoke a static method
$class = 'NameOfTheClass';
call_user_func( array( $class, 'nameOfStaticMethod' ) );
call_user_func( 'NameOfTheClass::nameOfStaticMethod' ); // (As of PHP 5.2.3)
Option 1 is faster than Option 2 so try to use them unless you don't know how many arguments your going to be passing to the method.
Edit: Previous editor did great job of cleaning up my answer but removed mention of call_user_func_array which is different then call_user_func.
PHP has
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
http://php.net/manual/en/function.call-user-func.php
AND
mixed call_user_func_array ( callable $callback , array $param_arr )
http://php.net/manual/en/function.call-user-func-array.php
Using call_user_func_array is orders of magnitude slower then using either option listed above.
You mean like this?
<?php
class A {
function test() {
print 'test';
}
}
$function = 'test';
// method 1
A::$function();
// method 2
$a = new A;
$a->$function();
?>
As of PHP7, you use an array-like way:
// Static call only
[TestClass::class, $methodName](...$args);
// Dynamic call, static or non-static doesn't matter
$instance = new TestClass();
[$instance, $methodName](...$args);
Just replace the class name with TestClass
, the method name with $methodName
and the method arguments with ...$args
. Note that, in the later case, it doesn't matter that the method is static or non-static.
One advantage is you can pass the array as a callable to a function.
There is a new first-class callable syntax in PHP 8.1:
$callable = TestClass::$methodName(...);
// Or
$callable = $instance->$methodName(...);
$callable(...$args);
call_user_func(array($object, 'methodName'));
For more details, see the php callback documentation.
EDIT: I just worked out what you were trying to ask... ah well.. will leave my comments in anyway. You can substitute names of classes and methods with variables if you like..(but you are crazy) - nick
To call a function from within a class you can do it one of two ways...
Either you can create an instance of the class, and then call it. e.g.:
$bla = new Blahh_class();
$bla->do_something();
or... you can call the function statically.. i.e. with no instance of the class. e.g.:
Blahh_class::do_something()
of course you do need to declare that your function is static:
class Blahh_class {
public static function do_something(){
echo 'I am doing something';
}
}
If a class is not defined as static, then you must create an instance of the object.. (so the object needs a constructor) e.g.:
class Blahh_class {
$some_value;
public function __construct($data) {
$this->$some_value = $data;
}
public function do_something() {
echo $this->some_value;
}
}
The important thing to remember is that static class functions can not use $this
as there is no instance of the class. (this is one of the reasons why they go much faster.)
This may be useful as a substitute
class ReferenceContainer {
function __construct(CallbackContainer $callbackContainer) {
//Alternatively you can have no parameters in this constructor and create a new instance of CallbackContainer and invoke the callback in the same manner
//var_dump($this->callbackContainer);
$data = 'This is how you parse a class by reference';
$callbackContainer->myCallback($data);
}
}
class CallbackContainer {
function __construct() {}
function myCallback($data) {
echo $data."\n";
}
}
$callbackContainer = new CallbackContainer();
$doItContainer = new ReferenceContainer($callbackContainer);