共计 2451 个字符,预计需要花费 7 分钟才能阅读完成。
参考资料:
laravel 底层外围代码剖析之外围概念解说
PHP 管制反转(IOC) 和依赖注入(DI)
1 – Laravel 框架外围
长处
- 集成了 composer
- 实现了依赖注入,更好的治理类的依赖关系,不便扩大(绝对于 MVC 模式)
- 高级个性:控制台 console,事件 event,队列 queue,中间件 middleware,门面模式 facades
- 外围概念:服务容器 serviceProvider
毛病及优化
毛病
- 加载文件太多,拜访速度慢
优化
- 缓存配置文件
- 去掉不必要的加载文件(次要是 serviceProvider)
- 开启 Opcache
框架启动流程(生命周期)
- 援用主动加载文件
- 生成服务容器
1) 注册根底的 bingings
2) 通过 bind 注册服务容器,事件,路由,日志服务
3) 通过 bind 绑定接口 - 获取 Request 对象
- 逻辑解决
1) 解析启动项(根底服务)如路由,异样解决,门面,服务容器
2) 通过管道模式,用中间件过滤用户申请,解决业务逻辑 - 返回 Response 对象
知识点
单例模式,观察者模式,管道模式
依赖注入,匿名函数,反射
预约义接口 ArrayAccess
2 – 管制反转和依赖注入
管制反转 IOC(inversion of control)
将组件间的依赖关系从程序外部提到内部来治理
解释:不在 A 类中间接新建 B 类实例,而是通过 IOC 容器将 B 类的实例传给 A
依赖注入 DI(dependency injection)
将组件的依赖通过内部以参数或其余模式注入
示例:
class DbMysql
{public function query(){}}
class IOC
{
public $db;
public function __construct($dbMysql)
{$this->db = $dbMysql;}
public function action()
{$this->db->query();
}
}
$db = new DbMysql();
$c = new IOC($db);
$c->action();
IOC 类中不须要实例化 DbMysql,而是将 DbMysql 的实例作为参数传入,仅调用 DbMysql 的办法。这种模式就是 依赖注入。
将 B 类的实例化动作提出到 IOC 类的里面,就叫做 管制反转。
PHP 的反射机制
在 PHP 运行时,扩大分析程序,导出或提出对于类,办法,属性,参数的详细信息,这种动静获取和调用信息的性能称为反射 API。
class A
{public function __construct(B $b)
{}}
class B
{
}
// 获取类的反射信息(所有信息)
$reflector = new ReflectionClass('A');
// 获取构造函数
$constructor = $reflector->getConstructor();
// 获取结构函数参数
$dependencies = $constructor->getParameters();
// 获取依赖的类名
foreach ($dependencies as $dependency){if(!is_null($dependency->getClass())){$classname = $dependency->getClass()->name;
$p[] = new $classname();
}
}
// 从给出的参数创立一个新的类实例
$a = $reflector->newInstanceArgs($p);
如果 B 类也有依赖的类,则须要通过递归创立
<?php
class A
{public function __construct(B $b)
{$this->b = $b;}
public function getB()
{$this->b->bMethod();
}
}
class B
{public function __construct(C $c,D $d)
{
$this->c = $c;
$this->d = $d;
}
public function bMethod()
{echo "我是 B 中的办法 bMethod()";
}
}
class C{public function __construct()
{ }
public function cMethod(){echo "我是 C 中的办法 cMethod()";
}
}
class D{public function __construct()
{ }
public function dMethod(){echo "我是 D 中的办法 dMethod()";
}
}
class Ioc
{protected $instances = [];
public function __construct()
{ }
public function getInstance($classname){$reflector = new ReflectionClass($classname);
$constructor = $reflector->getConstructor();
$dependencies = $constructor->getParameters();
if(!$dependencies){return new $classname();
}
foreach ($dependencies as $dependency){if(!is_null($dependency->getClass())){$instances[] = $this->make($dependency->getClass()->name);
}
}
return $reflector->newInstanceArgs($instances);
}
public function make($classname){return $this->getInstance($classname);
}
}
$ioc = new Ioc();
$a = $ioc->make('A');
$a->getB();
总结
PHP 程序运行的实质:蕴含文件,获取实例化对象。
传统框架:通过 include/require 来治理类的依赖关系。
Laravel:通过 namespace 和 use,实现了主动加载机制,找到类所在文件,而后通过反射获取类的实例化对象。
正文完