关于laravel:Laravel58底层学习笔记01-控制反转和依赖注入

27次阅读

共计 2451 个字符,预计需要花费 7 分钟才能阅读完成。

参考资料:
laravel 底层外围代码剖析之外围概念解说
PHP 管制反转(IOC) 和依赖注入(DI)

1 – Laravel 框架外围

长处

  1. 集成了 composer
  2. 实现了依赖注入,更好的治理类的依赖关系,不便扩大(绝对于 MVC 模式)
  3. 高级个性:控制台 console,事件 event,队列 queue,中间件 middleware,门面模式 facades
  4. 外围概念:服务容器 serviceProvider

毛病及优化

毛病

  1. 加载文件太多,拜访速度慢

优化

  1. 缓存配置文件
  2. 去掉不必要的加载文件(次要是 serviceProvider)
  3. 开启 Opcache

框架启动流程(生命周期)

  1. 援用主动加载文件
  2. 生成服务容器
    1) 注册根底的 bingings
    2) 通过 bind 注册服务容器,事件,路由,日志服务
    3) 通过 bind 绑定接口
  3. 获取 Request 对象
  4. 逻辑解决
    1) 解析启动项(根底服务)如路由,异样解决,门面,服务容器
    2) 通过管道模式,用中间件过滤用户申请,解决业务逻辑
  5. 返回 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,实现了主动加载机制,找到类所在文件,而后通过反射获取类的实例化对象。

正文完
 0