Как мне динамически вызывать метод класса в PHP? - PullRequest
50 голосов
/ 07 ноября 2008

Как я могу динамически вызывать метод класса в PHP? Метод класса не является статическим. Похоже, что

call_user_func(...)

работает только со статическими функциями?

Спасибо.

Ответы [ 8 ]

88 голосов
/ 07 ноября 2008

Работает в обоих направлениях - вам нужно использовать правильный синтаксис

//  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)
23 голосов
/ 08 ноября 2008

Вариант 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 на несколько порядков медленнее, чем использование любого из перечисленных выше вариантов.

16 голосов
/ 07 ноября 2008

Вы имеете в виду, как это?

<?php

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

$function = 'test';

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

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

?>
2 голосов
/ 07 ноября 2008
call_user_func(array($object, 'methodName'));

Подробнее см. В документации по обратному вызову php.

1 голос
/ 10 ноября 2008

РЕДАКТИРОВАТЬ: Я только что понял, что вы пытались спросить ... ну хорошо ... оставит мои комментарии в любом случае. Вы можете заменить имена классов и методов переменными, если вам нравится .. (но вы сошли с ума) - ник


Чтобы вызвать функцию из класса, вы можете сделать это одним из двух способов ...

Либо вы можете создать экземпляр класса, а затем вызвать его. e.g.:

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

или ... вы можете вызывать функцию статически ... т.е. без экземпляра класса. e.g.:

Blahh_class::do_something()

конечно, вам нужно объявить, что ваша функция статическая:

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

Если класс не определен как статический, вы должны создать экземпляр объекта .. (поэтому объекту нужен конструктор) e.g.:

class Blahh_class {
    $some_value;

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

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

Важно помнить, что статические функции класса не могут использовать $this, так как нет экземпляра класса. (это одна из причин, почему они идут намного быстрее.)

0 голосов
/ 03 мая 2016

Это может быть полезно в качестве замены

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 голосов
/ 23 июля 2013
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'));
0 голосов
/ 04 июня 2012

Лучший способ найти для меня это

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

Это работает как шарм!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...