ThinkPHP6容器与依赖注入
目录
容器和依赖注入大部分人官方文档难以消化,一方面两个概念不好理解,过于术语化,问文档范例没有更接地气的范例。
首先我们要弄明白依赖注入是什么,为什么需要依赖注入,可以看看:03-依赖倒置原则
如果还不懂得依赖注入的概念:
容器
ThinkPHP引入的容器,到底是什么意思?
官方是这么说的:ThinkPHP使用容器来更方便的管理类依赖及运行依赖注入。容器和依赖注入 · ThinkPHP6.0完全开发手册 · 看云
通俗点说就是:tp6实现了个容器类,这个类专门处理依赖注入的实例对象,比如框架内置绑定到容器中的类有:
内置类库 | 容器绑定标识 |
---|---|
think\Cache | cache |
think\Config | config |
think\Cookie | cookie |
think\Request | request |
think\Response | response |
think\Filesystem | filesystem |
think\Route | route |
think\Session | session |
- | - |
当然我们也可以将自定义类注入到容器中,供业务逻辑类使用,举个例子:
class A(){
private $b;
public function __construct(Request $request, B $b){
$this->b = $b;
}
}
class B(){
//...
}
//没有使用依赖注入之前,我们需要手动实例化B对象,并传参给类A,进行实例化:
$a = new A(new think\Request(), new B());
//如果使用tp6的依赖注入,通过助手函数invoke:
$a = invoke('A');//框架会通过依赖注入,将实例化B,并注册到框架容器中,省去了手动实例化,及可以在容器类中统一管理这些注入对象
依赖注入的类统一由容器进行管理,大多数情况下是在自动绑定并且实例化的。
绑定与解析类库
除了调用时自动注入容器外,我们还可以手动绑定类库到容器中。
可以对已有的类库绑定一个标识(唯一),便于快速调用。
// 绑定类库标识
$this->app->bind('think\Cache', 'app\common\Cache');
// 或者使用助手函数 绑定类库标识
bind('cache', 'think\Cache');
//绑定一个闭包
bind('sayHello', function ($name) {
return 'hello,' . $name;
});
// 绑定类实例
$cache = new think\Cache;
bind('cache', $cache);
//使用助手函数app解析使用容器中的类或对象或函数等
$cache = app('cache');
批量绑定
在实际应用开发过程,不需要手动绑定,我们只需要在app目录下面定义provider.php文件(只能在全局定义,不支持应用单独定义),系统会自动批量绑定类库到容器中。
return [
'route' => \think\Route::class,
'session' => \think\Session::class,
'url' => \think\Url::class,
];
注意:绑定标识主要是为了方便记住与快速使用,我们也可以解析一个未绑定的类,只是没有简短的标识,需要类完整命名空间路径:
$arrayItem = app('org\utils\ArrayItem');
依赖注入场景
了解了依赖注入后,再去看TP官方关于依赖注入的使用
依赖注入的对象参数支持多个,且与顺序无关
以下场景支持依赖注入:
- 控制器构造方法
- 控制器操作方法
- 路由的闭包定义
- 事件类的执行方法
- 中间件的执行方法等