Maison  >  Article  >  développement back-end  >  Explication détaillée des étapes pour implémenter l'injection de dépendances à l'aide de la réflexion de classe PHP

Explication détaillée des étapes pour implémenter l'injection de dépendances à l'aide de la réflexion de classe PHP

php中世界最好的语言
php中世界最好的语言original
2018-05-19 10:12:461842parcourir

Cette fois, je vous apporte une explication détaillée des étapes pour implémenter la réflexion de classe PHP Injection de dépendances, et quelles sont les précautions pour que la réflexion de classe PHP implémente l'injection de dépendances. est un cas pratique. Jetons un coup d'œil une fois.

PHP dispose d'une API de réflexion complète, offrant la possibilité d'effectuer de l'ingénierie inverse sur des classes, des interfaces, des fonctions, des méthodes et des extensions. Grâce aux capacités fournies par la réflexion de classe, nous pouvons savoir comment la classe est définie, quels attributs elle possède, de quelles méthodes elle dispose, quels paramètres possède la méthode, quel est le chemin d'accès au fichier de classe et d'autres informations très importantes. C'est également grâce à la réflexion des classes que de nombreux frameworks PHP peuvent implémenter l'injection de dépendances pour résoudre automatiquement les dépendances entre les classes, ce qui apporte une grande commodité à notre développement quotidien. Cet article explique principalement comment utiliser la réflexion de classe pour implémenter l'injection de dépendances (Dependency Injection). Il ne décrira pas chaque API de PHP Reflection une par une. Pour des informations détaillées de référence sur l'API, veuillez vous référer à la documentation officielle

Pour. meilleures informations Pour comprendre plus clairement, prenons un exemple pour examiner la réflexion de classe et comment implémenter l'injection de dépendances.

La classe suivante représente un point dans le système de coordonnées et possède deux attributs : abscisse x et ordonnée 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;
  }
}

La classe suivante représente un cercle. Vous pouvez voir qu'il y a un paramètre dans son constructeur qui est de la classe Point, c'est-à-dire que la classe Circle dépend du Point. classe.

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);
  }
}

ReflectionClass

Ensuite, nous utilisons la réflexion pour procéder à l'ingénierie inverse de la classe Circle.

Passez le nom de la classe Circle à réflexionClass pour instancier un objet de la classe ReflectionClass.

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

Constantes réfléchies de la classe

$reflectionClass->getConstants();

Renvoie un tableau associatif de noms et de valeurs de constantes

array(1) {
 ["PI"]=>
 float(3.14)
}

Obtenir des propriétés par réflexion

$reflectionClass->getProperties();

Renvoyer un tableau composé d'objets ReflectionProperty

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"
 }
}

Réfléchir la méthode définie dans la classe

$reflectionClass->getMethods();

Renvoie un tableau d'objets ReflectionMethod

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"
 }
}

Nous pouvons également obtenir la méthode constructeur de la classe séparément via getConstructor(), et sa valeur de retour est un objet ReflectionMethod .

$constructor = $reflectionClass->getConstructor();

Paramètres de la méthode Reflection

$parameters = $constructor->getParameters();

La valeur de retour est un tableau composé d'objets ReflectionParameter.

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

Injection de dépendances

D'accord, nous écrivons ensuite une fonction appelée make, passons le nom de la classe à la fonction make et renvoyons l'objet de la classe, dans make Cela nous aidera à injecter les dépendances de la classe, c'est-à-dire, dans ce cas, à injecter l'objet Point dans le constructeur de la classe Circle.

//构建类的对象
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;
}

Après avoir défini la méthode make, nous l'utilisons pour nous aider à instancier des objets de la classe Circle :

$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)*/

Je crois que vous maîtrisez la méthode après avoir lu le cas dans ce article, et il y a des choses plus excitantes. Veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

PHP utilise des astérisques pour remplacer certains caractères dans le nom d'utilisateur, le téléphone portable et l'adresse e-mail

PHP multi- mise en place d'une simulation de fil événement de vente flash (avec code)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn