如何在 PHP 中动态调用类方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/273169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:09:35  来源:igfitidea点击:

How do I dynamically invoke a class method in PHP?

phpcallback

提问by mmattax

How can I dynamically invoke a class method in PHP? The class method is not static. It appears that

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

call_user_func(...)

only works with static functions?

只适用于静态函数?

Thanks.

谢谢。

回答by Peter Bailey

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)

回答by David

Option 1

选项1

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

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

Option 2

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

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



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.

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

PHP has

PHP有

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

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

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

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.

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

回答by Jeremy Ruten

You mean like this?

你的意思是这样?

<?php

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

$function = 'test';

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

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

?>

回答by MAChitgarha

As of PHP7, you use an array-like way:

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

// 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 $methodNameand the method arguments with ...$args. Note that, in the later case, it doesn't matter that the method is static or non-static; PHP will call it automatically.

只需用 替换类名,用 替换TestClass方法名,用替换$methodName方法参数...$args。请注意,在后一种情况下,该方法是静态的还是非静态的并不重要;PHP 会自动调用它。

回答by Neil Williams

call_user_func(array($object, 'methodName'));

For more details, see the php callback documentation.

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

回答by Bingy

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

编辑:我刚刚弄清楚你想问什么......嗯......无论如何都会留下我的评论。如果你愿意,你可以用变量替换类和方法的名称......(但你疯了) - 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 $thisas there is no instance of the class. (this is one of the reasons why they go much faster.)

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

回答by Osin Toumani

THe best way i find is to do

我发现最好的方法是做

call_user_func_array(array(__NAMESPACE__ .'\Foo', 'test'), array('Philip'));

It's working like a charm !

它的工作就像一个魅力!

回答by Nanhe Kumar

Class Foo{
 public function show(){
  echo 'I am in Foo Class show method';
 }

}

call_user_func(array('Foo', 'show'));

$classname = new Foo;
call_user_func(array($classname, 'show'));
call_user_func($classname .'::show'); // As of 5.2.3

$foo = new Foo();    
call_user_func(array($foo, 'show'));

回答by user2288580

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