Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung dynamischer Instanziierungsobjekte im PHP-Framework

Detaillierte Erläuterung dynamischer Instanziierungsobjekte im PHP-Framework

伊谢尔伦
伊谢尔伦Original
2017-06-26 14:09:322734Durchsuche

Bei der Framework-Entwicklung, der modularen Entwicklung usw. müssen wir möglicherweise Objekte dynamisch instanziieren, während PHP ausgeführt wird.

Was ist ein dynamisches Instanziierungsobjekt? Werfen wir zunächst einen Blick auf das Konzept einer Variablenfunktion (Variablenfunktion) in PHP. Zum Beispiel der folgende Code:

function foo() {
    echo 'This is the foo function';
}
$bar = 'foo';
$bar();

Beim Ausführen des obigen Codes wird „Dies ist“ ausgegeben die foo-Funktion" . Einzelheiten finden Sie im PHP-Handbuch: Variablenfunktionen. Wenn Sie dynamisch aufrufen müssen, verwenden Sie natürlich die Funktion call_user_func oder call_user_func_array. Die Verwendung dieser beiden Funktionen steht nicht im Mittelpunkt dieses Artikels. Wenn Sie dies nicht verstehen, lesen Sie bitte andere Informationen. Zurück zum Thema dieses Artikels: Was ist ein dynamisch instanziiertes Objekt? Ich glaube, dass die dynamische Instanziierung von Objekten bedeutet, dass die Objekte, die instanziiert werden müssen, während der Laufzeit des Programms dynamisch bestimmt (durch Variablen bestimmt) werden (durch Variablen bestimmt) und nicht direkt im Code fest codiert sind.

Anhand der obigen Beispiele wissen wir bereits, wie man eine Funktion zur Laufzeit dynamisch aufruft. Wenn die Objektorientierung heute so beliebt ist, müssen wir in einigen Codes eine Klasse dynamisch instanziieren zu tun?

Situation 1: Der Konstruktor der Klasse hat keine Parameter oder die Anzahl der Parameter ist bestimmt

Wenn der Konstruktor der Klasse keine Parameter oder die gewünschte Klasse hat Zum Instanziieren gibt es überhaupt keine Parameter. Ohne einen Konstruktor scheint es etwas einfacher zu sein. Sie können es gemäß dem obigen Beispiel ändern. Wer kann das nicht?

Codebeispiel. (Der Konstruktor hat keine Parameter)

class FOO {
    private $a, $b;
    public function construct() {
        $this->a = 1;
        $this->b = 2;
    }
    public function test() {
        echo &#39;This is the method test of class FOO<br />&#39;;
        echo &#39;$this->a=&#39;, $this->a, &#39;, $this->b=&#39;, $this->b;
    }
}
$bar = &#39;FOO&#39;;
$foo = new $bar();
$foo->test();

Führen Sie ihn aus und Sie werden die folgende Ausgabe sehen:

This is the method test of class FOO
$this->a=1, $this->b=2

Nun, wenn wir Parameter übergeben wollen, dann machen wir Folgendes:

class FOO {
    private $a, $b;
    public function construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }
    public function test() {
        echo &#39;This is the method test of class FOO<br />&#39;;
        echo &#39;$this->a=&#39;, $this->a, &#39;, $this->b=&#39;, $this->b;
    }
}
$bar = &#39;FOO&#39;;
$foo = new $bar(&#39;test&#39;, 5);
$foo->test();

Sie können ähnliche Ergebnisse erzielen:

This is the method test of class FOO
$this->a=test, $this->b=5

Ideal.

Fall 2: KlassenkonstruktionDie Anzahl der Funktionsparameter ist ungewiss

Diese Situation wird viel problematischer sein, aber wenn Sie es universeller schreiben möchten, dann einfach Diese Situation muss berücksichtigt werden. Wir haben zum Beispiel die folgenden zwei Klassen

class FOO {
    public function test() {
        echo &#39;This is the method test of class FOO&#39;;
    }
}
class BAR {
    private $a, $b;
    public function construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }
    public function test() {
        echo &#39;This is the method test of class BAR<br />&#39;;
        echo &#39;$this->a=&#39;, $this->a, &#39;, $this->b=&#39;, $this->b;
    }
}

und wir wollen eine gemeinsame Methode zur Instanziierung dieser beiden Klassen. Wir haben festgestellt, dass die FOO-Klasse keinen Konstruktor hat, oder es kann davon ausgegangen werden, dass die Anzahl der Parameter des Konstruktors der FOO-Klasse Null ist, während der Konstruktor der BAR-Klasse Parameter hat. Glücklicherweise ist PHP5 leistungsstark genug und führt das Konzept der Reflektion ein. Weitere Informationen finden Sie im PHP-Handbuch: Reflection, obwohl es im Handbuch nichts zu lesen gibt :). Glücklicherweise ist die Benennung gut geschrieben. Anhand des Klassennamens und des Methodennamens können Sie sich bereits eine ungefähre Vorstellung machen, sodass Sie nicht zu viele Wörter benötigen.

Nun, lasst uns PHP5-Reflexion verwenden, um diese Angelegenheit zu beginnen:

(Studenten, die immer noch PHP4 verwenden, gehen bitte nicht weg. Wenn Sie eine PHP-Version ohne Reflexion haben oder Liegt das daran? Aus Kompatibilitätsgründen oder weil Sie kein Upgrade durchführen möchten, möchten Sie Reflection nicht verwenden. Unten finden Sie eine Lösung.

$class = new ReflectionClass(&#39;FOO&#39;);
$foo = $class->newInstance(); //或者是$foo = $class->newInstanceArgs();
$foo->test();

Haben Sie etwas gesehen? Als nächstes:

$class = new ReflectionClass(&#39;BAR&#39;);
$bar = $class->newInstanceArgs(array(55, 65));
$bar->test();

OK, es scheint in Ordnung zu sein, also lassen Sie uns eine allgemeine Funktion entwickeln. Wir möchten sie so entwerfen. Die erste Funktion dieser Funktion ist der Name der Klasse Von Der zweite Parameter beginnt mit den Parametern des Konstruktors der zu instanziierenden Klasse. Wenn es mehrere gibt, notieren Sie sie. Um eine Funktion mit einer variablen Anzahl von Parametern zu implementieren, haben wir zwei Methoden:

Die erste ist eine Methode ähnlich wie:

function foo($arg1, $arg2 = 123, $arg3 = &#39;test&#39;, $arg4 = null, ....... ) {
    //some code;
}

Diese Methode hat zwei Nachteile: Die erste ist Wenn Sie 100 Parameter übergeben müssen, sollten Sie dann einfach 100 Parameter schreiben? Zweitens müssen Sie bestimmen, welcher Parameter im Programm null oder ein anderer Standardwert ist. (Exkurs: Der Standardwert des Parameters muss bei dieser Schreibweise am Ende stehen. Sie können einen Parameter ohne Standardwert nicht in der Mitte oder vor einem Parameter mit Standardwert einfügen. Andernfalls müssen Sie dies auch explizit tun Schreiben Sie den Parameter mit einem Standardwert, wenn Sie ihn aufrufen.)

Eine andere Möglichkeit, eine variable Anzahl von Parametern zu implementieren, ist die Verwendung der in PHP integrierten Funktion func_get_args (klicken Sie hier, um die zu lesen Handbuch), um die an die Funktion übergebenen Parameter in der Funktion zu erhalten. Ähnliche Funktionen umfassen func_get_num und func_get_arg. Vergiss es, ich bin faul. Du kannst das Handbuch finden und es selbst lesen.

Dann scheint es viel bequemer zu sein, diese Funktion zu verwenden. Basierend auf der imaginären Anordnung der

Funktionsparameter sollte der Code wie folgt aussehen:

function newInstance() {
    $arguments = func_get_args();
    $className = array_shift($arguments);
    $class = new ReflectionClass($className);
    return $class->newInstanceArgs($arguments);
}
OK, schauen wir uns den Effekt an:

$foo = newInstance(&#39;FOO&#39;);
$foo->test();
//输出结果:
//This is the method test of class FOO
$bar = newInstance(&#39;BAR&#39;, 3, 5);
$bar->test();
//输出结果:
//This is the method test of class BAR
//$this->a=3, $this->b=5
Mit nur vier Codezeilen ist der Effekt ziemlich perfekt. Wenn wir diese Idee dann auf eine Klasse anwenden, können wir sie direkt als

Magische Methode schreiben, was unsere Klasse cooler machen kann!

class INSTANCE {
    function call($className, $arguments) {
        $class = new ReflectionClass($className);
        return $class->newInstanceArgs($arguments);
    }
}
$inst = new INSTANCE();
$foo = $inst->foo();
$foo->test();
//输出结果:
//This is the method test of class FOO
$bar = $inst->bar(&#39;arg1&#39;, &#39;arg2&#39;);
$bar->test();
//输出结果:
//This is the method test of class BAR
//$this->a=3, $this->b=5
Kaka, genieße es.

Lassen Sie uns als Nächstes die Situation besprechen, ohne Reflexionskurse zu nutzen. Beispielsweise gibt es in PHP4 keine Reflexion und einige alte Projekte laufen auf PHP4. Oder wenn Sie die Kompatibilität des Projekts mit unbekannten Umgebungen sicherstellen möchten, kümmern wir uns um die dynamische Übertragung von Parametern. In PHP gibt es nur eine Funktion zur dynamischen Parameterübertragung: call_user_func_array (klicken Sie hier, um das Handbuch anzuzeigen). Dies ist eine Funktion, die eine Funktion dynamisch aufruft. Ihre Funktion besteht darin, die Parameter der Funktion in Form eines Arrays an die aufzurufende Funktion zu übergeben. Nun, ich war selbst verwirrt, also schauen wir uns das Beispiel direkt an:

function foo($a, $b) {
    echo &#39;$a=&#39;, $a, &#39;<br />&#39;;
    echo &#39;$b=&#39;, $b;
}
call_user_func_array(&#39;foo&#39;, array(1, &#39;string&#39;));
//本例输出结果:
//$a=1
//$b=string

那么,要实现用这种方法来动态实例化对象并传参,呃……,只有曲线救国了,我们得先写一个函数,让这个函数来实例化对象,而这个函数的参数就原原本本地传给要实例化对象的类的构造函数就好了。打住!那这个函数得有几个参数啊?怎么实现传递不同个数的参数呢?嘿嘿,我一声冷笑,你忘了PHP里提供一个创建匿名函数的函数吗?(又开始绕起来了……)create_function(手册在此),照着手册里面的例子直接画就可以了,我也懒得打字了,直接看下面的代码,注释我写清楚点大家都明白了:

function newInst() {
    //取得所有参数
    $arguments = func_get_args();
    //弹出第一个参数,这是类名,剩下的都是要传给实例化类的构造函数的参数了
    $className = array_shift($arguments);
    //给所有的参数键值加个前缀
    $keys = array_keys($arguments);
    array_walk($keys, create_function(&#39;&$value, $key, $prefix&#39;, &#39;$value = $prefix . $value;&#39;), &#39;$arg_&#39;);
    //动态构造实例化类的函数,主要是动态构造参数的个数
    $paramStr = implode(&#39;, &#39;,$keys);
    $newClass=create_function($paramStr, "return new {$className}({$paramStr});");
    //实例化对象并返回
    return call_user_func_array($newClass, $arguments);
}

好了,至于效果是什么,就麻烦各位看官自己动动手,运行一下看看,是不是自己期望的结果。

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung dynamischer Instanziierungsobjekte im PHP-Framework. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn