Contracts, ServiceContainer, ServiceProvider, Facades關系
概念
-
Contracts 合同,契約,也就是接口,定義一些規則,每個實現此接口的都要實現里面的方法
-
ServiceContainer 實現Contracts,具體的邏輯實現
-
ServiceProvider ServiceContainer的服務提供者,返回ServiceContainer的實例化,供其他地方使用,可以把它加入到app/config的provider中,會被自動注冊到容器中
-
Facades 簡化ServiceProvider的調用方式,而且可以靜態調用ServiceContainer中的方法
實現
Contracts接口可以寫或不寫,這里就不定義了定義一個ServiceContainer,實現具體的功能
namespace App\Helper;
class MyFoo{
public function add($a, $b)
{
return $a+$b;
}
}
定義一個ServiceProvider供其他地方使用ServiceContain
<?phpnamespace App\Providers;
use App\Helper\MyFoo; //要服務的Containeruse Illuminate\Support\ServiceProvider;
use App;
class MyFooServiceProvider extends ServiceProvider{
public function boot(){}
//注冊到容器中
public function register()
{
//可以這么綁定,這需要use App;
App::bind("myfoo",function(){
return new MyFoo();
});
//也可以這么綁定
$this->app->bind("myfoo", function(){
return new MyFoo();
});
}
}
在app/config.php中的providers數組中加入ServiceProvider,讓系統自動注冊
App\Providers\MyFooServiceProvider::class,
這時候就可以使用了,假設在控制器中使用
public function two($id=null){
//從系統容器中獲取實例化對象
//app('myfoo')->add(1,2);
$myfoo = App::make("myfoo");
echo $myfoo->add(1,2);
}
這樣太麻煩,還需要用make來獲取對象,為了簡便,就可以使用門面功能,定義門面MyFooFacade
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class MyFooFacade extends Facade{
protected static function getFacadeAccessor()
{
//這里返回的是ServiceProvider中注冊時,定義的字符串
return 'myfoo';
}
}
在控制器里就可以直接調用了
use App\Facades\MyFooFacade;
public function two($id=null){
//從系統容器中獲取實例化對象
$myfoo = App::make("myfoo");
echo $myfoo->add(1,2);
//使用門面
echo MyFooFacade::add(4,5);
}
總的來說,自定義了一個類,為了方便在其他別處使用,便可以使用服務提供者和門面
----------------------------華麗的分割線----------------------------
簡單的說,“服務容器”就是“服務提供者”提供的服務的容器,“服務容器”通過“服務提供者”來獲取服務。
一個laravel應用就是一個“服務容器”,整個框架提供的各種功能由“服務提供者”提供並注入到“服務容器”中。每一個“服務提供者”里register的方法里面使用bind邦定某個對象到一個變量,那個對象就是真正提供服務的對象。
轉自:https://segmentfault.com/a/1190000004965752#articleHeader4