web-dev-qa-db-fra.com

Comment invoquer dynamiquement une méthode de classe en PHP?

Comment puis-je invoquer dynamiquement une méthode de classe en PHP? La méthode de classe n'est pas statique. Il semble que 

call_user_func(...)

ne fonctionne qu'avec des fonctions statiques?

Merci.

50
mmattax

Cela fonctionne dans les deux sens - vous devez utiliser la bonne syntaxe

//  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)
88
Peter Bailey

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)

L'option 1 est plus rapide que l'option 2, essayez donc de les utiliser à moins que vous ne sachiez combien d'arguments vous allez transmettre à la méthode.


Edit: L'éditeur précédent a parfaitement nettoyé ma réponse, mais a supprimé la mention de call_user_func_array qui est différente de call_user_func. 

PHP a 

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

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

ET 

mixed call_user_func_array ( callable $callback , array $param_arr )

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

L'utilisation de call_user_func_array est un ordre de grandeur plus lent que l'utilisation de l'une des options répertoriées ci-dessus.

22
David

Tu veux dire comme cela?

<?php

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

$function = 'test';

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

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

?>
16
Jeremy Ruten
call_user_func(array($object, 'methodName'));

Pour plus de détails, consultez la documentation de php callback.

2
Neil Williams

EDIT: Je viens de travailler sur ce que vous essayez de demander ... ah bien .. va laisser mes commentaires dans de toute façon. Vous pouvez remplacer les noms de classes et méthodes par des variables si vous le souhaitez .. (mais vous êtes fou) - nick


Pour appeler une fonction depuis une classe, vous pouvez le faire de deux manières ...

Soit vous pouvez créer une instance de la classe, puis l’appeler . Exemple:

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

ou ... vous pouvez appeler la fonction de manière statique .. c'est-à-dire sans instance de la classe .

Blahh_class::do_something()

bien sûr, vous devez déclarer que votre fonction est statique:

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

Si une classe n'est pas définie en tant que statique, vous devez alors créer une instance de l'objet .. (l'objet a donc besoin d'un constructeur) Exemple:

class Blahh_class {
    $some_value;

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

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

La chose importante à retenir est que les fonctions de classe statiques ne peuvent pas utiliser $this car il n'y a pas d'instance de la classe. (C’est l’une des raisons pour lesquelles ils vont beaucoup plus vite.)

1
Bingy

Le meilleur moyen que je trouve est de faire 

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

Cela fonctionne comme un charme!

0
Osin Toumani

Cela peut être utile comme substitut

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
user2288580
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
Nanhe Kumar