lavarel服務提供者

先看一篇好的介紹:

前言
剛開始看 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 的自動加載機制,這樣是不是更能提高你的效率呢。

————————————————
原文作者:xiaocailc
轉自鏈接:https://learnku.com/articles/17638
版權聲明:著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請保留以上作者信息和原文鏈接。

 

總結:

剛看的時候不瞭解一個類我直接use就行了,爲什麼還要去註冊一次。現在瞭解了。比如:我a類和b類都繼承了c接口。我現在在服務提供者裏註冊a類。那麼通過c調用的都是a類的方法。但如果我之後想全部換成b類。則直接在註冊這裏把a類改成b類就好了。最明顯的就是我把緩存從最初的mem改成redis.只要實現的是同一個緩存接口。就只需要改服務提供者這裏的註冊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章