前言
剛開始看laravel服務容器、契約、服務提供器的確生澀難懂,不單單是概念繁多,而且實際的demo很難找(找是找到了,但難用啊),最後就隔一段時間看一遍,大概個十來遍,還真給看出個門道,廢話少說上程式碼。
準備階段
首先宣告一下我的測試環境
php 7.2.4
laravel 5.6
1.建立新專案(composer)
在你的專案目錄命令列執行:
composer create-project laravel/laravel laravelapp --prefer-dist
2.建立服務提供器
生成檔案位於:專案/app/Providers/TestServiceProvider
php artisan make:provider TestServiceProvider
同時修改配置檔案config/app.php,在providers陣列中追加該服務提供器
'providers' => [
App\Providers\TestServiceProvider::class,
],
3.建立自己的工作目錄(xiaocai)
我的工作目錄在:專案/app/Xiaocai目錄下
// 目錄結構
|---app
|---Xiaocai
|---Test
|---DemoInterface.php
|---DemoProvider.php
|---DemoProvider2.php
寫到這裡你可能問我的工作目錄下三個檔案幹什麼用呢?不要著急,接下來我們逐個建立檔案並進行講解。
1:DemoInterface.php【介面檔案】這個就是laravel中提到的Contracts(契約),使用介面(契約)的原因官方也給了說明:低耦合和簡單性,檔案內容如下:
<?php
namespace App\Xiaocai\Test;
interface DemoInterface
{
function demo1();
function demo2();
}
介面中只簡單定義兩個測試方法,記住帶上名稱空間App\Xiaocai\Test,這個很重要;
2:DemoProvider.php【介面實現類】,這個官方並沒有特別說明,當然,有了介面當然會有對應的實現類去實現介面中的方法
檔案內容如下:
<?php
namespace App\Xiaocai\Test;
class DemoProvider implements DemoInterface
{
public function demo1()
{
return 'demo1';
}
public function demo2()
{
return 'demo2';
}
}
對於這個實現類,我是這樣理解的,laravel中的契約(介面)通過規定好方法名稱,這樣,第三方擴充套件包在想要實現這些契約方法的時候,必然要受到契約提供的方法的約束,防止濫用,使使用者在使用laravel基礎上的擴充套件包的時候,不必要再去了解底層程式碼邏輯,方法都是定義好的,儘管不同的包處理的邏輯不同,但是對於使用者來說,都是呼叫的同一個方法,對於如何選擇到底使用哪個實現類,我們也準備好了DemoProvider2.php類,他是DemoInterface.php的第二種實現方法。
3:DemoProvider2.php【介面實現類2】內容如下
<?php
namespace App\Xiaocai\Test;
class DemoProvider2 implements DemoInterface
{
public function demo1()
{
return 'demo1的第二種實現';
}
public function demo2()
{
return 'demo2的第二種實現';
}
}
4.建立測試控制器
命令列執行:
php artisan make:controller TestController
5.新增路由
為測試控制器新增一個測試路由,修改專案/routes/web.php檔案,追加程式碼如下:
Route::get('/test', 'TestController@index');
6.修改服務提供器檔案(TestServiceProvider)
這裡是重點!這裡是重點!這裡是重點!重要的事情我只說三遍
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Xiaocai\Test\DemoInterface;
use App\Xiaocai\Test\DemoProvider;
use App\Xiaocai\Test\DemoProvider2;
class TestServiceProvider extends ServiceProvider
{
public function boot()
{
}
public function register()
{
$this->app->bind(DemoInterface::class, DemoProvider2::class);
}
}
在這裡就可以對想要使用的實現介面(契約)類進行選擇,$this->app->bind(arg1, arg2);引數1代表介面類,引數2代表要使用的介面實現類,你可以在這裡進行切換選擇實現類,切換之後如何驗證呢?
驗證
修改TestController檔案
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Xiaocai\Test\DemoInterface;//注意引用的是介面檔案,並非實現類
class TestController extends Controller
{
public function index(DemoInterface $demo)
{
dd($demo->demo1());
}
}
此時瀏覽器輸出介面不出意外的話應該是這樣的:
我們不妨修改一下實現類,在TestServiceProvider檔案中修改如下:
$this->app->bind(DemoInterface::class, DemoProvider::class);
//$this->app->bind(DemoInterface::class, DemoProvider2::class);
此時再執行,如下:
總結
如此一來,切換實現的方法是不是很簡單,只需要在服務提供器中修改即可,果真是低耦合。如果文章中出現什麼紕漏歡迎指出,防止禍害他人,如果覺得對您有幫助的話,點個贊支援一下吧。
結語
另外Xiaocai工作目錄是測試用的,當然如果做專案的話,你也可以把你的程式碼上傳到composer,這樣通過composer直接引入到vendor目錄下,通過composer的自動載入機制,這樣是不是更能提高你的效率呢。
本作品採用《CC 協議》,轉載必須註明作者和本文連結