依賴注入
ThinkPHP的依賴注入(也稱之為控制反轉(zhuǎn))是一種較為輕量的實(shí)現(xiàn),無需任何的配置,并且主要針對(duì)訪問控制器進(jìn)行依賴注入。可以在控制器的構(gòu)造函數(shù)或者操作方法(指訪問請(qǐng)求的方法)中類型聲明任何(對(duì)象類型)依賴,這些依賴會(huì)被自動(dòng)解析并注入到控制器實(shí)例或方法中。
自動(dòng)注入請(qǐng)求對(duì)象
架構(gòu)方法注入
在控制器的架構(gòu)方法中會(huì)自動(dòng)注入當(dāng)前請(qǐng)求對(duì)象,例如:
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') . '!';
}
}
操作方法注入
控制器的操作方法中如果需要調(diào)用請(qǐng)求對(duì)象Request
的話,可以在方法中定義Request
類型的參數(shù),并且參數(shù)順序無關(guān),例如:
namespace app\index\controller;
use think\Request;
class Index
{
public function hello(Request $request)
{
return 'Hello,' . $request->param('name') . '!';
}
}
訪問URL地址的時(shí)候 無需傳入request
參數(shù),系統(tǒng)會(huì)自動(dòng)注入當(dāng)前的Request
對(duì)象實(shí)例到該參數(shù)。
如果繼承了系統(tǒng)的Controller
類的話,也可以直接調(diào)用request
屬性,例如:
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
public function hello()
{
return 'Hello,'.$this->request->param('name');
}
}
其它對(duì)象自動(dòng)注入(V5.0.1
)
從5.0.1
版本開始,控制器的架構(gòu)方法和操作方法支持任意對(duì)象的自動(dòng)注入。
架構(gòu)方法注入
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;
}
}
對(duì)于已經(jīng)進(jìn)行了綁定(屬性注入)的對(duì)象,即可自動(dòng)完成依賴注入,如果沒有進(jìn)行對(duì)象綁定的話,會(huì)自動(dòng)實(shí)例化一個(gè)新的對(duì)象示例傳入(如果類定義有
instance
方法,則會(huì)自動(dòng)調(diào)用instance
方法進(jìn)行實(shí)例化)。
架構(gòu)方法的依賴注入不影響其它類型的參數(shù)綁定。
操作方法注入
我們把User
模型綁定到當(dāng)前請(qǐng)求對(duì)象:
Request::instance()->bind('user', \app\index\model\User::get(1));
然后就可以在操作方法中進(jìn)行對(duì)象參數(shù)的自動(dòng)注入,代碼:
<?php
namespace app\index\controller;
use app\index\model\User;
use think\Controller;
class Index extends Controller
{
public function hello(User $user)
{
return 'Hello,'.$user->name;
}
}
如果沒有事先在Request對(duì)象中進(jìn)行對(duì)象綁定的話,調(diào)用hello
方法的時(shí)候user
參數(shù)會(huì)自動(dòng)實(shí)例化,相當(dāng)于完成了下面的綁定操作:
Request::instance()->bind('user', new \app\index\model\User);
對(duì)象自動(dòng)注入不影響原來的參數(shù)綁定。
invoke方法自動(dòng)調(diào)用(v5.0.2
)
5.0.2版本開始,如果依賴注入的類有定義一個(gè)可調(diào)用的靜態(tài)invoke
方法,則會(huì)自動(dòng)調(diào)用invoke方法完成依賴注入的自動(dòng)實(shí)例化。
invoke
方法的參數(shù)是當(dāng)前請(qǐng)求對(duì)象實(shí)例,例如:
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);
}
}