IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 【深入理解laravel前提】一步一步从依赖注入和控制反转实现一个超级简单IOC容器 适合小白食用 -> 正文阅读

[PHP知识库]【深入理解laravel前提】一步一步从依赖注入和控制反转实现一个超级简单IOC容器 适合小白食用

懵懂时,我一直不理解为什么要有IOC容器这东西,composer不是已经可以实现自动加载了吗?

一个开发框架有很多的类库、实例等等需要管理和调用,IOC容器可以让我们更好的管理我们的类和对象,当前主流的框架已经离不开它了

别走客官,这是学习武林秘籍第一步,想要习得上层武功,必经之路呀,否则你只能去隔壁练葵花宝典了!

学习它之前,我们需要弄清2个概念
1. 依赖注入
1. 控制反转
最后我们将实现一个简单的自动依赖注入的IOC容器

依赖注入


我想 new 一个实例,但是这个实例中还需要 new 另外一个实例,也就是说两个实例对应的类是包含(组合)关系。

别逼逼,上代码

class A {
? ? private $objB;
? ? public function __construct (B $obj) {
? ? ? ? $this->objB = $obj;
? ? }
}
class B {}

//想拿A就得new B,嘿嘿
$instance = new A(new B());


依赖注入表示的是两个类的实例之间的共存关系

控制反转


为什么要有控制反转呢,上面的依赖注入是我们手动完成的,当某个对象需要另外一个对象的时候,我们就直接手动给它 new 一个出来,有没有更加高效的方式呢?IOC 控制反转应运而生,因为不需要你手动new就能自动产生你需要对象,怎么样,很神奇吧!

说到控制反转,我们不得不提的编程语言的反射机制,试想一下 new 一个类的时候,我只要知道类名就能实例化,是不是意味着只要你给我名字,我就控制了你这个类,那么我们称之为反射。

1. 告诉我你需要的类的名字叫A,我通过一个叫ReflectionClass 来获得他的反射对象$reflector

$reflector = new ReflectionClass('App\A');


2. isInstantiable() 检查类是否可实例化,newInstance()获得一个实例

if ($reflector->isInstantiable()) {
? return $refector->newInstance();?
}


怎么样,能拿到想要的实例吧,试想一下,如果我们把这种好用的特性结合到依赖注入会怎么样呢,是不是意味着我们就不用手动 new 实例了,直接拿到类名,自动 new 呗,还要啥自行车。

一个类实例化肯定会调用构造方法 `__construct()` 我们抓住这一点

$constructor = $reflector->getConstructor();
$dependencies = $constructor->getParameters();//获得构造方法的参数


你依赖的类这下全部给我在$dependencies中了吧,那么我一个个new 不就来了么

$dependenciesInstances = [];
foreach($dependencies as $dependency) {
? ? $reflector = new ReflectionClass($dependency);
? ? $dependenciesInstances[] = $refector->newInstance();?
}


至此,我们是不是可以通过构造方法自动new依赖的实例了,效率大大的提高。## 实现一个很简单的自动依赖注入工厂类
下面我们来写一个简单的自动依赖注入的工厂来解决我们开头说重复 new 的问题

class IocFactory {
? ? /**
? ? ?* make依赖实例
? ? ?* @param $class
? ? ?* @return object
? ? ?* @throws ReflectionException
? ? ?*/
? ? public static function make($class) {
? ? ? ? $reflector = new ReflectionClass($class);
? ? ? ? $constructor = $reflector->getConstructor();

? ? ? ? if (is_null($constructor)) {
? ? ? ? ? ? if ($reflector->isInstantiable()) {
? ? ? ? ? ? ? ? return $reflector->newInstance();
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? $dependenciesArgs = [];
? ? ? ? $dependencies = $constructor->getParameters();//获得构造方法的参数
? ? ? ? foreach($dependencies as $dependency) {
? ? ? ? ? ? //实例化依赖
? ? ? ? ? ? $dependenciesArgs[] = self::make($dependency->getName());
? ? ? ? }
? ? ? ? return $reflector->newInstanceArgs($dependenciesArgs);
? ? }
}


下面我们声明三个类,A类包含B类包含C类 ?也就是 A=>B=>C

class A {
? ? private $b;
? ? public function __construct(B $b)
? ? {
? ? ? ? $this->b = $b;
? ? }
}
class B {
? ? private $c;
? ? public function __construct(C $c)
? ? {
? ? ? ? $this->c = $c;
? ? }
}
class C {

}

现在可以实例化A,就可以自动帮我们把B和C也实例化

$obj = IocFactory::make(A::class);
var_dump($obj);


结果

object(A)#6 (1) {
? ["b":"A":private]=>
? object(B)#7 (1) {
? ? ["c":"B":private]=>
? ? object(C)#8 (0) {
? ? }
? }
}

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-08-28 08:48:43  更:2021-08-28 08:50:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:25:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码