🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 容器 * 容器来更方便的管理类依赖及运行依赖注入。 * 容器类`think\container`。容器类主要是维护`$instances`容器对象数组,和`$bind`容器绑定标识。 * 容器类 可通过容器绑定标识,利用反射机制进行实例化对象,并绑定到容器对象数组中。 * 手动绑定到容器标识`$this->app->bind('标识名', '类名')`, 也可直接绑定一个对象到容器中`$this->app->bind('标识名', '对象')` * 配置文件绑定。 可通过app目录下`provider.php`文件,进行配置需要绑定到容器标识。在App实例化的时候,批量加载此文件,进行绑定。 ### 依赖注入 * 利用容器类的反射机制进行实例化类的时候, 都支持依赖注入。如控制器架构方法,控制器操作方法,事件类的执行方法,中间件类的执行方法。或者使用`invoke()`助手函数,实例化对象。 * 将类绑定到容器标识的类,也可以支持依赖注入。 ### 调用 * 可通过app对象直接调用容器中的对象,如`$this->app->http`。框架会自动再容器对象数组中,获取该对象,如果没有,则查找容器标识数组,找出对应的类,进行实例化返回,并存储这个实例到容器对象数组中。 ### 依赖注入 ### 容器 ### 门面 文章目录 1.什么是依赖注入? 1.1 依赖注入的概念: 1.2 依赖注入的举例: 2.什么是容器? 2.1 容器的概念: 2.2 容器的举例: 3.门面是什么? 3.1 门面的概念: 3.2 门面的好处: 3.3框架已有的常用类的代理: 3.3 门面的举例: 4.依赖注入和门面的对比: 4.1 依赖注入的实现方式: 4.2 门面(静态代理)的实现方式: 4.3 使用父类的属性的实现方法: 以下是关于 《最新ThinkPHP 5.1全球首发视频教程》的第4章的笔记 1.什么是依赖注入? 1.1 依赖注入的概念: 依赖注入指的是将对象类型的数据以参数的方式传到一个方法的参数列表中 1.2 依赖注入的举例: ``` <?php class Site { public $siteNum=123; public function getNum() { return $this->siteNum; } } //Site $site这里就是依赖注入,等同于在方法里面写$site=new Site(); function test(Site $site){ return $site->getNum(); } ``` 2.什么是容器? 2.1 容器的概念: 在tp中可以把类注册进容器中,想用这个类的实例对象时,可用容器实例化一个类对象来使用。 2.2 容器的举例: 将Demo1注册进容器中,再用容器实例化一个Demo1对象。 ``` <?php namespace app\index\controller; class Index { public function bindClass(){ //1.把Demo1这个类注册到容器中 //第一个参数是类的别名(可自定义),第二个参数是类的命名空间+类名 \think\Container::set('demo1','\app\index\controller\Demo1'); //2.把容器中的类实例化并取出 //第一个参数是类注册时的别名,第二个参数是类的构造函数所需的参数名=>参数值 $demo1=\think\Container::get('demo1',['num'=>456]); //3.此时可以使用容器实例出的类对象来调用类方法 return $demo1->getName(); } } ``` 被注册的类Demo1 ``` <?php namespace app\index\controller; class Demo1 { private $num; public function __construct($num){ $this->num=$num; } public function getName(){ return $this->num; } } ``` 3.门面是什么? 3.1 门面的概念: 如果想实现静态的去调用一个类的所有的动态(和静态)方法,则可以定义一个Facade的子类,定义一个方法用于返回该类,就可以想调用类方法时,从动态调用$class->function()变成静态调用class::function() 3.2 门面的好处: 给所有的调用方式提供了一个同一的接口(都用静态调用的形式),代码清晰规范(不会到处都是对象),方便调试 3.3框架已有的常用类的代理: 其实tp框架中的常用类都定义了Facade类库(位置为\think\facade目录),定义后无需实例化就可以直接静态调用类的方法。 3.3 门面的举例: Demo1类中有一个getNum的方法 ``` <?php namespace app\index\controller; class Demo1 { private $num=123; public function getNum() { return $this->num; } } ``` 创建一个Facade类的子类,用来静态代理Demo1类(建议同名因为便于管理) ``` <?php namespace app\facade; class Demo1 extends \think\Facade { //重写Facade类的getFacadeClass函数,直接返回本子类所代理的真正类的命名空间 protected static function getFacadeClass() { return '\app\index\controller\Demo1'; } } ``` 代理完毕,现在在别的类中可以直接静态调用Demo1的方法 ``` <?php namespace app\index\controller; use app\facade\Demo1; class Index { public function test(){ return Demo1::getNum(); } } ``` 如果上面的形式觉得不够灵活,可以换成动态绑定代理关系,如下: 首先让刚才创建的Facade的子类中的内容为空 ``` <?php namespace app\facade; class Demo1 extends \think\Facade { } ``` 然后在需要调用Demo1类的位置进行动态绑定bind(facade子类,子类所代理的类本身); 调用完bind()函数后就可以静态调用Demo1的动态方法了。 ``` <?php namespace app\index\controller; class Index { public function test() { \think\Facade::bind('app\facade\Demo1','app\index\controller\Demo1'); return \app\facade\Demo1::getNum(); } } ``` 4.依赖注入和门面的对比: 假如目标是在一个控制器中获取GET请求参数 4.1 依赖注入的实现方式: ``` <?php namespace app\index\controller; class Index { public function test(\think\Request $request) { dump($request->get()); } } ``` 4.2 门面(静态代理)的实现方式: ``` <?php namespace app\index\controller; class Index { public function test() { dump(\think\facade\Request::get()); } } ``` 4.3 使用父类的属性的实现方法: 继承Controller后,使用Controller类中的保护型属性$request(这是Request类实例) ``` <?php namespace app\index\controller; class Index extends \think\Controller { public function test () { dump($this->request->get()); } } ```