Dynamischer Klassenmethodenaufruf in PHP


85

Gibt es eine Möglichkeit, eine Methode in derselben Klasse für PHP dynamisch aufzurufen? Ich habe nicht die richtige Syntax, aber ich möchte etwas Ähnliches tun:

$this->{$methodName}($arg1, $arg2, $arg3);

War es die ursprüngliche Frage? Ich wollte eine Methode dynamisch aufrufen und fand diese Frage. Es ist dieselbe Syntax wie bei andy.gurin und ich sehe keinen Link, der das Update der Frage anzeigt. Wie auch immer ... Danke gefragt zu haben und danke an die Mitwirkenden :-)
Luc M

5
@ Luc - Es war die ursprüngliche Frage. Es stellte sich heraus, dass ich die richtige Syntax hatte, als ich fragte, aber etwas anderes stimmte nicht mit meinem Code, so dass es nicht funktionierte.
VirtuosiMedia

Antworten:


172

Es gibt mehr als einen Weg, dies zu tun:

$this->{$methodName}($arg1, $arg2, $arg3);
$this->$methodName($arg1, $arg2, $arg3);
call_user_func_array(array($this, $methodName), array($arg1, $arg2, $arg3));

Sie können sogar die Reflection-API http://php.net/manual/en/class.reflection.php verwenden


Ich denke, vielleicht hatte ich die richtige Syntax, also stimmt etwas anderes mit meinem Code nicht, da er nicht ganz richtig funktioniert. Hmm ...
VirtuosiMedia

Ein Wort an die Müden, wenn Ihre Methoden für Objekte aufgerufen und mit PHPUnit getestet werden, call_user_func_arrayist das Richtige für Sie.
OK sicher

Du mein Freund, hast gerade meinen Tag gerettet! Ich rief an call_user_func_array($this->$name, ...)und fragte mich , warum es nicht funktionieren würde!
Pubudu Dodangoda


10

Sie können das Überladen in PHP verwenden: Überladen

class Test {

    private $name;

    public function __call($name, $arguments) {
        echo 'Method Name:' . $name . ' Arguments:' . implode(',', $arguments);
        //do a get
        if (preg_match('/^get_(.+)/', $name, $matches)) {
            $var_name = $matches[1];
            return $this->$var_name ? $this->$var_name : $arguments[0];
        }
        //do a set
        if (preg_match('/^set_(.+)/', $name, $matches)) {
            $var_name = $matches[1];
            $this->$var_name = $arguments[0];
        }
    }
}

$obj = new Test();
$obj->set_name('Any String'); //Echo:Method Name: set_name Arguments:Any String
echo $obj->get_name();//Echo:Method Name: get_name Arguments:
                      //return: Any String


3

Wenn Sie in einer Klasse in PHP arbeiten, würde ich empfehlen, die überladene __call-Funktion in PHP5 zu verwenden. Die Referenz finden Sie hier .

Grundsätzlich macht __call für dynamische Funktionen das, was __set und __get für Variablen in OO PHP5 tun.


2

Nach all den Jahren immer noch gültig! Stellen Sie sicher, dass Sie $ methodName kürzen, wenn es sich um benutzerdefinierten Inhalt handelt. Ich konnte $ this -> $ methodName nicht zum Laufen bringen, bis ich bemerkte, dass es ein führendes Leerzeichen hatte.


Wenn es sich um benutzerdefinierten Inhalt handelt, stellen Sie sicher, dass Sie viel mehr tun, als nur den Namen zu kürzen! Wie ... Sicherheitskontrolle! ;)
Erk

Irgendwo im Internet habe ich detailliert beschrieben, wie der vom Benutzer eingegebene utf8 in Windows-sichere Zeichen konvertiert wird. QuickBooks hat mich durch diesen Wringer geführt - und warum QB nicht mehr dazu beiträgt, wie ich Verkäufe abschließe ...
Chris K

Erlauben Sie dem Client wirklich, eine Eingabe anzugeben, die einige Methoden dynamisch aufruft ?! Ich habe keine Worte
Mcsky

Offensichtlich validiert und überprüft, dass die Klasse tatsächlich eine solche benannte Methode enthält. Es gibt viele Möglichkeiten, den Wert zu überprüfen. Es schlägt eine lange switch-Anweisung.
Snapey

1

In meinem Fall.

$response = $client->{$this->requestFunc}($this->requestMsg);

Verwenden von PHP SOAP.


2
Ich bin nicht sicher, aber seien Sie vorsichtig mit Sicherheitsproblemen
tom10271

1

Sie können eine Methode mithilfe eines Abschlusses in einer einzelnen Variablen speichern:

class test{        

    function echo_this($text){
        echo $text;
    }

    function get_method($method){
        $object = $this;
        return function() use($object, $method){
            $args = func_get_args();
            return call_user_func_array(array($object, $method), $args);           
        };
    }
}

$test = new test();
$echo = $test->get_method('echo_this');
$echo('Hello');  //Output is "Hello"

BEARBEITEN: Ich habe den Code bearbeitet und jetzt ist er mit PHP 5.3 kompatibel. Ein weiteres Beispiel hier

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.