laravel 的 ServiceProvider 的 boot 方法和 providers 方法如何使用

來源:互聯網
上載者:User
能不能舉個例子? 文檔好像很不詳細
對於剛理解 IOCDI 概念的我, 勉強只能看懂 register 方法在做什麼
有人幫忙解釋下嗎

回複內容:

能不能舉個例子? 文檔好像很不詳細
對於剛理解 IOCDI 概念的我, 勉強只能看懂 register 方法在做什麼
有人幫忙解釋下嗎

如果你對 IoCDI 還有點模糊,可以參考如下連結,建議按照如下順序進行閱讀:

1.Laravel 官方文檔中對 Service Container 和 Service Provider 的描述,按照目前的積累的經驗進行初步理解

2.一個形象的 IoC 概述

3.通過簡單的 PHP 代碼描述 IoC

4.IoC 的用途、分類的詳細敘述

最後再回過頭來再參考一下 Service Container 和 Service Provider 文檔,並且查看使用者請求的生命週期概述:Request Lifecycle,基本上都可以非常清晰的理解。

現在有了 IoCLaravel 請求生命週期的基礎,瞭解 ServiceProvider 就不會太難。

ServiceProvider

繼承自 ServiceProvider 的類中一般重寫兩個重要的函數:register 和 boot 方法。

0x0. 突發奇想

有一天我突然想用 Laravel 實現一個程式,通過輸入問題來擷取 SegmentFault 上的答案列錶鏈接,廢話少說上代碼:

class SegmentFault {    private $server;    public function __construct($server)    {        $this->server = $server;    }        /**    * Retrieve the answers    */    public function answer($question)    {        return  $this->server . $question;    }}

回到 Controller,現在來調用 SegmentFault 這個類。你需要手動去執行個體化他嗎?不,Laravel 會自動幫你執行個體化:

public function index(SegmentFault $segmentFault) {    return $segmentFault->answer('What is Service Provider in Laravel ?');  }

看來我寶刀未老,加上優美的 Laravel 架構分分鐘搞定,激動的我趕緊重新整理一下頁面:

臣蔔木曹,報錯了,看錯誤提示明顯是沒辦法解析 SegmentFault 的參數,說好的自動依賴注入呢!?

不對,我需要傳入 SegmentFault 的搜尋連結參數(不然 Laravel 怎麼會知道需要構造什麼參數呢),但是這樣子要手動執行個體化。。不就傳個參數嗎,我傳:

public function index() {    $segmentFault = new SegmentFault('https://segmentfault.com/search?q=');    return $segmentFault->answer('What is Service Provider in Laravel ?');  }

這回沒問題了。

0x1. 開始偷懶

現在我想在其他頁面也提供這個功能,似乎每次都要去執行個體化有點麻煩啊。假如有一天 SegmentFault 換了網域名稱,就要修改十幾個函數......

想想這嚴重的結果,不得不改進這個程式。好,回頭來看 IoC。既然 SegmentFault 這個類執行個體化時需要傳入參數,搜搜文檔,原來還挺簡單的,先建個 ServiceProvider 調教一下:

class SegmentFaultServiceProvider extends ServiceProvider {    public function register() {        $this->app->bind(SegmentFault::class, function() {            return new SegmentFault('https://segmentfault.com/search?q=');        });    }}

這樣子一來就把依賴資訊配置好了,Laravel 知道怎麼正確執行個體化這個類了,趕緊改寫程式:

public function index(SegmentFault $segmentFault) {    return $segmentFault->answer('What is Service Provider in Laravel ?');}

咦,重新整理網頁還是報錯了!? 哦對了,還需要在 config/app.php 中註冊這個 Provider:

'providers' => [    // ...    App\Providers\SegmentFaultServiceProvider::class,]

再重新整理,現在可以正常工作了,So cool !! 我不禁從椅子上跳起來。

0x2. 總結

IoC 是將內部設計的類交給系統去控制,但是有些類在初始化的時候,需要制定特定的參數,或者當你需要將實作類別綁定到某個介面,這時候就必須對這些依賴進行配置,系統才能正確解析並引用。

register

而 register 就是這樣一個地方,你可以在 register 配置類的依賴,綁定實作類別到介面,設定類的別名等等。

boot

而 boot 方法在 register 方法之後調用,這就意味著,你無須擔心在注入某個執行個體的時候,他還沒有被綁定或執行個體化。

例如你建立了 SegmentFault 和 SegmentFaultApi 兩個類,前者依賴與後者,但是在 register 中你不確定那個類先被執行個體化了,那麼你可以在 boot 中再對後者進行引用,因為此時兩個類都已經進行正確的配置。

providers

providers 方法用於消極式載入的 ServiceProvider,比如希望在引用的時候再讓系統去解析那個類,那麼可以設定 $defer 變數為 true 來延遲啟動,節省開銷:

protected $defer = true;

當設定了延遲啟動,需要重寫 providers 函數。當 Laravel 遇到消極式載入的類,只要在每個 ServiceProvider 中的 providers 函數中搜尋制定的引用關鍵字,便可以調用正確 register 函數的解析該類:

public function providers() {    return [SegmentFault::class];}

這是筆者的一片文章:PHP Laravel 一個請求的處理過程。(當然因為時間關係還沒有寫完,待續23333

有錯誤的地方希望大牛指正,Thx~

以上。

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.