Detaillierte Erläuterung des Abhängigkeitsinjektionsprozesses der PHP-Klassenreflexionsimplementierung

小云云
Freigeben: 2023-03-19 22:22:01
Original
2377 Leute haben es durchsucht

PHP verfügt über eine vollständige Reflexions-API, die die Möglichkeit bietet, Klassen, Schnittstellen, Funktionen, Methoden und Erweiterungen zurückzuentwickeln. Durch die von der Klassenreflexion bereitgestellten Funktionen können wir wissen, wie die Klasse definiert ist, welche Attribute sie hat, welche Methoden sie hat, welche Parameter die Methode hat, wie der Pfad zur Klassendatei lautet und andere sehr wichtige Informationen. Aufgrund der Klassenreflexion können viele PHP-Frameworks auch die Abhängigkeitsinjektion implementieren, um die Abhängigkeiten zwischen Klassen automatisch aufzulösen, was unserer täglichen Entwicklung große Erleichterung bringt.

In diesem Artikel wird hauptsächlich erläutert, wie die Klassenreflexion zum Implementieren der Abhängigkeitsinjektion (Abhängigkeitsinjektion) verwendet wird. Detaillierte API-Referenzinformationen finden Sie in der offiziellen Dokumentation. In diesem Artikel werden wir hauptsächlich die Reflexion der PHP-Klasse vorstellen, um den Abhängigkeitsinjektionsprozess zu realisieren und verwandte Wissenspunkte auszutauschen. Ich hoffe, dass es jedem helfen kann, dem Editor zu folgen.

Für ein besseres Verständnis schauen wir uns die Klassenreflexion und die Implementierung der Abhängigkeitsinjektion anhand eines Beispiels an.

Die folgende Klasse stellt einen Punkt im Koordinatensystem dar und hat zwei Attribute: Abszisse x und Ordinate y.


/**
 * Class Point
 */
class Point
{
  public $x;
  public $y;

  /**
   * Point constructor.
   * @param int $x horizontal value of point's coordinate
   * @param int $y vertical value of point's coordinate
   */
  public function __construct($x = 0, $y = 0)
  {
    $this->x = $x;
    $this->y = $y;
  }
}
Nach dem Login kopieren

Die nächste Klasse stellt einen Kreis dar. Sie können sehen, dass es in ihrem Konstruktor einen Parameter der Point-Klasse gibt, der von der Circle-Klasse abhängt Punktklasse.


class Circle
{
  /**
   * @var int
   */
  public $radius;//半径

  /**
   * @var Point
   */
  public $center;//圆心点

  const PI = 3.14;

  public function __construct(Point $point, $radius = 1)
  {
    $this->center = $point;
    $this->radius = $radius;
  }
  
  //打印圆点的坐标
  public function printCenter()
  {
    printf('center coordinate is (%d, %d)', $this->center->x, $this->center->y);
  }

  //计算圆形的面积
  public function area()
  {
    return 3.14 * pow($this->radius, 2);
  }
}
Nach dem Login kopieren

ReflectionClass

Als nächstes verwenden wir Reflection, um die Circle-Klasse zurückzuentwickeln.

Übergeben Sie den Namen der Circle-Klasse an ReflectionClass, um ein Objekt der ReflectionClass-Klasse zu instanziieren.


$reflectionClass = new reflectionClass(Circle::class);
//返回值如下
object(ReflectionClass)#1 (1) {
 ["name"]=>
 string(6) "Circle"
}
Nach dem Login kopieren

Konstante, die die Klasse widerspiegelt


$reflectionClass->getConstants();
Nach dem Login kopieren

Gibt ein An zurück Assoziatives Array bestehend aus konstanten Namen und Werten


array(1) {
 ["PI"]=>
 float(3.14)
}
Nach dem Login kopieren

Erhalten Sie Eigenschaften durch Reflexion


$reflectionClass->getProperties();
Nach dem Login kopieren

Gibt ein Array aus ReflectionProperty-Objekten zurück


array(2) {
 [0]=>
 object(ReflectionProperty)#2 (2) {
  ["name"]=>
  string(6) "radius"
  ["class"]=>
  string(6) "Circle"
 }
 [1]=>
 object(ReflectionProperty)#3 (2) {
  ["name"]=>
  string(6) "center"
  ["class"]=>
  string(6) "Circle"
 }
}
Nach dem Login kopieren

Gibt die in der Klasse definierten Methoden wider


$reflectionClass->getMethods();
Nach dem Login kopieren

Gibt ein Array von ReflectionMethod-Objekten zurück


array(3) {
 [0]=>
 object(ReflectionMethod)#2 (2) {
  ["name"]=>
  string(11) "__construct"
  ["class"]=>
  string(6) "Circle"
 }
 [1]=>
 object(ReflectionMethod)#3 (2) {
  ["name"]=>
  string(11) "printCenter"
  ["class"]=>
  string(6) "Circle"
 }
 [2]=>
 object(ReflectionMethod)#4 (2) {
  ["name"]=>
  string(4) "area"
  ["class"]=>
  string(6) "Circle"
 }
}
Nach dem Login kopieren

Wir können die Konstruktormethode der Klasse auch separat über getConstructor abrufen (), sein Rückgabewert ist ein ReflectionMethod-Objekt.


$constructor = $reflectionClass->getConstructor();
Nach dem Login kopieren

Reflection-Methodenparameter


$parameters = $constructor->getParameters();
Nach dem Login kopieren

Der Rückgabewert ist ein Array von ReflectionParameter-Objekten.


array(2) {
 [0]=>
 object(ReflectionParameter)#3 (1) {
  ["name"]=>
  string(5) "point"
 }
 [1]=>
 object(ReflectionParameter)#4 (1) {
  ["name"]=>
  string(6) "radius"
 }
}
Nach dem Login kopieren

Abhängigkeitsinjektion

Okay, als nächstes schreiben wir eine Funktion namens make und übergeben die Klasse. Der Name lautet Das von der Make-Funktion zurückgegebene Objekt der Klasse hilft uns, die Abhängigkeiten der Klasse einzufügen, d. h. in diesem Fall hilft es uns, das Point-Objekt in den Konstruktor der Circle-Klasse einzufügen.


//构建类的对象
function make($className)
{
  $reflectionClass = new ReflectionClass($className);
  $constructor = $reflectionClass->getConstructor();
  $parameters = $constructor->getParameters();
  $dependencies = getDependencies($parameters);
  
  return $reflectionClass->newInstanceArgs($dependencies);
}

//依赖解析
function getDependencies($parameters)
{
  $dependencies = [];
  foreach($parameters as $parameter) {
    $dependency = $parameter->getClass();
    if (is_null($dependency)) {
      if($parameter->isDefaultValueAvailable()) {
        $dependencies[] = $parameter->getDefaultValue();
      } else {
        //不是可选参数的为了简单直接赋值为字符串0
        //针对构造方法的必须参数这个情况
        //laravel是通过service provider注册closure到IocContainer,
        //在closure里可以通过return new Class($param1, $param2)来返回类的实例
        //然后在make时回调这个closure即可解析出对象
        //具体细节我会在另一篇文章里面描述
        $dependencies[] = '0';
      }
    } else {
      //递归解析出依赖类的对象
      $dependencies[] = make($parameter->getClass()->name);
    }
  }

  return $dependencies;
}
Nach dem Login kopieren

Nachdem wir die make-Methode definiert haben, verwenden wir sie, um Objekte der Circle-Klasse zu instanziieren:


$circle = make('Circle');
$area = $circle->area();
/*var_dump($circle, $area);
object(Circle)#6 (2) {
 ["radius"]=>
 int(1)
 ["center"]=>
 object(Point)#11 (2) {
  ["x"]=>
  int(0)
  ["y"]=>
  int(0)
 }
}
float(3.14)*/
Nach dem Login kopieren

Verwandte Empfehlungen:

Instanzanalyse der Abhängigkeitsinjektion von Laravel

Detaillierte Erläuterung der PHP-Methode der automatischen Abhängigkeitsinjektion basierend auf dem Reflexionsmechanismus

So analysieren Sie die PHP-Abhängigkeitsinjektion

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Abhängigkeitsinjektionsprozesses der PHP-Klassenreflexionsimplementierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!