Pour comprendre les deux concepts d'injection de dépendances PHP et d'inversion de contrôle, vous devez comprendre les problématiques suivantes :
DI——Injection de dépendances
IoC——Inversion de contrôle
1. Qui sont les participants ?
Réponse : Généralement, il y a trois parties, l'une est un objet ; l'une est le conteneur d'IoC/DI ; l'autre est la ressource externe d'un objet. Laissez-moi vous expliquer à nouveau les noms. Un objet fait référence à n'importe quel objet Java ordinaire ; le conteneur IoC/DI fait simplement référence à un programme-cadre utilisé pour implémenter les fonctions IoC/DI ; les ressources externes de l'objet font référence à l'objet. de l'extérieur de l'objet, sont collectivement appelés ressources, telles que : d'autres objets nécessaires à l'objet, ou des ressources de fichiers nécessaires à l'objet, etc.
2. Dépendance : Qui dépend de qui ? Pourquoi y a-t-il des dépendances ?
Réponse : Un objet dépend du conteneur IoC/DI. Les dépendances sont inévitables. Dans un projet, il existe diverses relations entre les différentes classes, et il est impossible qu'elles soient toutes complètement indépendantes, ce qui forme des dépendances. Le développement traditionnel utilise des appels directs lors de l'utilisation d'autres classes, ce qui formera un couplage fort, qui doit être évité. L'injection de dépendances emprunte des conteneurs pour transférer les objets dépendants afin de réaliser le découplage.
3. Injection : Qui injecte à qui ? Qu'est-ce qui est injecté exactement ?
Réponse : Injecter les ressources externes dont il a besoin dans l'objet via le conteneur
4. Inversion de contrôle : Qui contrôle qui ? Contrôler quoi ? Pourquoi parle-t-on de renversement ?
Réponse : L'objet de contrôle de conteneur d'IoC/DI contrôle principalement la création d'instances d'objet. L’inversion est relative à la direction positive, alors qu’est-ce qui compte comme direction positive ? Pensez à l'application dans des circonstances normales. Si vous souhaitez utiliser C dans A, que feriez-vous ? Bien entendu, l'objet de C est créé directement, c'est-à-dire que la ressource externe requise C est activement obtenue dans la classe A. Cette situation est appelée en avant. Alors, qu’est-ce que l’inverse ? Autrement dit, la classe A n'obtient plus activement C, mais attend passivement que le conteneur IoC/DI obtienne une instance de C, puis l'injecte dans la classe A à l'envers.
5. L'injection de dépendances et l'inversion de contrôle sont-elles le même concept ?
Réponse : Comme le montre ce qui précède : l'injection de dépendances est décrite du point de vue de l'application. L'injection de dépendances peut être décrite plus en détail : l'application dépend du conteneur. pour créer et injecter les ressources externes requises ; alors que l'inversion de contrôle est décrite du point de vue du conteneur, la description est complète : le conteneur contrôle l'application, et le conteneur injecte à l'envers les ressources externes requises par l'application dans l'application.
Examinons de plus près quelques méthodes d'implémentation de injection de dépendances à travers des exemples :
1. Injection de constructeur
<?php class Book { private $db_conn; public function __construct($db_conn) { $this->db_conn = $db_conn; } }
2. Injection de Setter
<?php class book{ private $db; private $file; function setdb($db){ $this->db=$db; } function setfile($file){ $this->file=$file; } } class file{} class db{} ... class test{ $book = new Book(); $book->setdb(new db()); $book->setfile(new file()); } ?>
Le code des deux méthodes ci-dessus est très clair, mais lorsqu'on a besoin d'injecter beaucoup de dépendances, cela implique d'ajouter beaucoup de lignes, ce qui sera difficile à gérer.
Une meilleure solution consiste à créer une classe comme conteneur pour toutes les dépendances. Dans cette classe, vous pouvez stocker, créer, obtenir et trouver les dépendances requises
.<?php class Ioc { protected $db_conn; public static function make_book() { $new_book = new Book(); $new_book->set_db(self::$db_conn); //... //... //其他的依赖注入 return $new_book; } }
À ce stade, si vous souhaitez obtenir une instance de livre, il vous suffit d'exécuter $newone = Ioc::makebook();
Ce qui précède est un exemple spécifique de conteneur. Il est préférable de ne pas écrire de méthode d'injection de dépendances spécifique. Il est préférable d'utiliser l'enregistrement dans le registre et d'obtenir l'acquisition.
<?php class Ioc { /** * @var 注册的依赖数组 */ protected static $registry = array(); /** * 添加一个resolve到registry数组中 * @param string $name 依赖标识 * @param object $resolve 一个匿名函数用来创建实例 * @return void */ public static function register($name, Closure $resolve) { static::$registry[$name] = $resolve; } /** * 返回一个实例 * @param string $name 依赖的标识 * @return mixed */ public static function resolve($name) { if ( static::registered($name) ) { $name = static::$registry[$name]; return $name(); } throw new Exception('Nothing registered with that name, fool.'); } /** * 查询某个依赖实例是否存在 * @param string $name id * @return bool */ public static function registered($name) { return array_key_exists($name, static::$registry); } }
Vous pouvez désormais vous inscrire et en injecter un via les méthodes suivantes
<?php $book = Ioc::registry('book', function(){ $book = new Book; $book->setdb('...'); $book->setprice('...'); return $book; }); //注入依赖 $book = Ioc::resolve('book'); ?>
Ce qui précède est la compréhension de l'injection de dépendances PHP et de l'inversion de contrôle. J'espère qu'il sera utile à tout le monde d'apprendre la programmation PHP.