依赖注入

最后更新于:2022-04-01 21:20:15

ThinkPHP的依赖注入(也称之为控制反转)是一种较为轻量的实现,无需任何的配置,并且主要针对访问控制器进行依赖注入。可以在控制器的构造函数或者操作方法(指访问请求的方法)中类型声明任何(对象类型)依赖,这些依赖会被自动解析并注入到控制器实例或方法中。 ## 自动注入请求对象 ### 架构方法注入 在控制器的架构方法中会自动注入当前请求对象,例如: ~~~ namespace app\index\controller; use think\Request; class Index { protected $request; public function __construct(Request $request) { $this->request = $request; } public function hello() { return 'Hello,' . $this->request->param('name') . '!'; } } ~~~ ### 操作方法注入 控制器的操作方法中如果需要调用请求对象`Request`的话,可以在方法中定义`Request`类型的参数,并且参数顺序无关,例如: ~~~ namespace app\index\controller; use think\Request; class Index { public function hello(Request $request) { return 'Hello,' . $request->param('name') . '!'; } } ~~~ 访问URL地址的时候 无需传入`request`参数,系统会自动注入当前的`Request`对象实例到该参数。 如果继承了系统的`Controller`类的话,也可以直接调用`request`属性,例如: ~~~ request->param('name'); } } ~~~ ## 其它对象自动注入(`V5.0.1`) 从`5.0.1`版本开始,控制器的架构方法和操作方法支持任意对象的自动注入。 ### 架构方法注入 ~~~ namespace app\index\controller; use app\index\model\User; use think\Request; class Index { protected $request; protected $user; public function __construct(Request $request, User $user) { $this->request = $request; $this->user = $user; } } ~~~ > 对于已经进行了绑定(属性注入)的对象,即可自动完成依赖注入,如果没有进行对象绑定的话,会自动实例化一个新的对象示例传入(如果类定义有`instance`方法,则会自动调用`instance`方法进行实例化)。 架构方法的依赖注入不影响其它类型的参数绑定。 ### 操作方法注入 我们把`User`模型绑定到当前请求对象: ~~~ Request::instance()->bind('user', \app\index\model\User::get(1)); ~~~ 然后就可以在操作方法中进行对象参数的自动注入,代码: ~~~ name; } } ~~~ 如果没有事先在Request对象中进行对象绑定的话,调用`hello`方法的时候`user`参数会自动实例化,相当于完成了下面的绑定操作: ~~~ Request::instance()->bind('user', new \app\index\model\User); ~~~ > 对象自动注入不影响原来的参数绑定。 ## invoke方法自动调用(`v5.0.2`) 5.0.2版本开始,如果依赖注入的类有定义一个可调用的静态`invoke`方法,则会自动调用invoke方法完成依赖注入的自动实例化。 `invoke`方法的参数是当前请求对象实例,例如: ~~~ namespace app\index\model; use think\Model; class User extends Model { public static function invoke(Request $request) { $id = $request->param('id'); return User::get($id); } } ~~~
';