参考资料:
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,实现了主动加载机制,找到类所在文件,而后通过反射获取类的实例化对象。