如何在 PHP 中动态调用类方法?[复制]

How do I dynamically invoke a class method in PHP? [duplicate]

提问人:mmattax 提问时间:11/8/2008 最后编辑:hakremmattax 更新时间:7/27/2023 访问量:76532

问:

如何在PHP中动态调用类方法?类方法不是静态的。看来

call_user_func(...)

仅适用于静态函数?

谢谢。

PHP 回调

评论


答:

2赞 Neil Williams 11/8/2008 #1
call_user_func(array($object, 'methodName'));

有关详细信息,请参阅 php 回调文档。

101赞 Peter Bailey 11/8/2008 #2

它是双向的 - 您需要使用正确的语法

//  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)

评论

3赞 e-motiv 5/4/2014
而这些:stackoverflow.com/questions/251485/......
0赞 ihsanberahim 9/30/2018
还有这个:stackoverflow.com/questions/41124015/......
19赞 Paige Ruten 11/8/2008 #3

你是说这样?

<?php

class A {
    function test() {
        print 'test';
    }
}

$function = 'test';

// method 1
A::$function();

// method 2
$a = new A;    
$a->$function();

?>
34赞 David 11/8/2008 #4

选项 1

// invoke an instance method
$instance = new Instance();
$instanceMethod = 'bar';
$instance->$instanceMethod();

// invoke a static method
$class = 'NameOfTheClass';
$staticMethod = 'blah';
$class::$staticMethod();

选项 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)

选项 1 比选项 2 快,因此请尝试使用它们,除非您不知道要传递给该方法多少个参数。


编辑:以前的编辑在清理我的答案方面做得很好,但删除了对call_user_func_array的提及,这与call_user_func不同。

PHP有

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) 

http://php.net/manual/en/function.call-user-func.php

mixed call_user_func_array ( callable $callback , array $param_arr )

http://php.net/manual/en/function.call-user-func-array.php

使用call_user_func_array比使用上面列出的任一选项慢几个数量级。

2赞 Bingy 11/10/2008 #5

编辑:我刚刚弄清楚你想问什么......啊好吧..无论如何都会留下我的评论。如果您愿意,可以将类和方法的名称替换为变量。(但你疯了)——尼克


要从类中调用函数,可以通过以下两种方式之一进行调用......

您可以创建该类的实例,然后调用它。 例如:

$bla = new Blahh_class();
$bla->do_something();

或。。。您可以静态调用该函数。即没有类的实例。 例如:

Blahh_class::do_something()

当然,你确实需要声明你的函数是静态的:

class Blahh_class {   
    public static function do_something(){
        echo 'I am doing something';
    }
}

如果未将类定义为静态类,则必须创建该对象的实例。(所以对象需要一个构造函数) 例如:

class Blahh_class {
    $some_value;

    public function __construct($data) {
        $this->$some_value = $data;
    }

    public function do_something() {
         echo $this->some_value;
    }
}

要记住的重要一点是,静态类函数不能使用,因为没有类的实例。 (这是它们运行得更快的原因之一。$this

0赞 user2288580 5/3/2016 #6

这可以作为替代品

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);

评论

0赞 Rudiger W. 3/26/2018
这个想法可以通过使用接口(即 ICallbackContainer)进一步改进。
7赞 MAChitgarha 7/17/2019 #7

从 PHP7 开始,您使用类似数组的方式:

// Static call only
[TestClass::class, $methodName](...$args);

// Dynamic call, static or non-static doesn't matter
$instance = new TestClass();
[$instance, $methodName](...$args);

只需将类名替换为 ,将方法名称替换为 ,将方法参数替换为 。请注意,在后一种情况下,方法是静态的还是非静态的并不重要。TestClass$methodName...$args

一个优点是可以将数组作为可调用对象传递给函数。

更新:PHP 8.1

PHP 8.1 中有一个新的一类可调用语法

$callable = TestClass::$methodName(...);
// Or
$callable = $instance->$methodName(...);

$callable(...$args);