鍍金池/ 教程/ PHP/ 服務提供者
門面
Laravel Homestead
安裝及配置
測試
HTTP 中間件
加密
升級指南
幫助函數(shù)
應用目錄結(jié)構(gòu)
集合
新手入門指南-簡單任務管理系統(tǒng)
任務調(diào)度
查詢構(gòu)建器
視圖
驗證
Laravel Cashier(訂購&支付&發(fā)票)
本地化
隊列
調(diào)整器
分頁
文件系統(tǒng)/云存儲
貢獻代碼
哈希
HTTP 控制器
緩存
遷移
HTTP 請求
Laravel Elixir
發(fā)行版本說明
Envoy 任務運行器(SSH任務)
序列化
Session
起步
帶用戶功能的任務管理系統(tǒng)
起步
用戶授權(quán)
郵件
事件
填充數(shù)據(jù)
HTTP 路由
服務提供者
Blade 模板引擎
包開發(fā)
用戶認證
Artisan 控制臺
HTTP 響應
集合
服務容器
關(guān)聯(lián)關(guān)系
一次請求的生命周期
契約
Redis
錯誤&日志

服務提供者

1、簡介

服務提供者是所有 Laravel 應用啟動的中心,你自己的應用以及所有 Laravel 的核心服務都是通過服務提供者啟動。

但是,我們所謂的”啟動“指的是什么?通常,這意味著注冊事物,包括注冊服務容器綁定、時間監(jiān)聽器、中間件甚至路由。服務提供者是應用配置的中心。

如果你打開 Laravel 自帶的 config/app.php 文件,將會看到一個 providers 數(shù)組,這里就是應用所要加載的所有服務提供者類,當然,其中很多是延遲加載的,也就是說不是每次請求都會被加載,只有真的用到它們的時候才會加載。

本章里你將會學習如何編寫自己的服務提供者并在 Laravel 應用中注冊它們。

2、編寫服務提供者

所有的服務提供者繼承自 Illuminate\Support\ServiceProvider 類。繼承該抽象類要求至少在服務提供者中定義一個方法:register。在 register 方法內(nèi),你唯一要做的事情就是綁事物到服務容器,不要嘗試在其中注冊任何時間監(jiān)聽器,路由或者任何其它功能。

通過 Artisan 命令 make:provider 可以簡單生成一個新的提供者:

php artisan make:provider RiakServiceProvider

2.1 register 方法

正如前面所提到的,在register 方法中只綁定事物到服務容器,而不要做其他事情,否則話,一不小心就能用到一個尚未被加載的服務提供者提供的服務。

現(xiàn)在讓我們來看看一個基本的服務提供者長什么樣:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider{
    /**
     * 在容器中注冊綁定.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('Riak\Contracts\Connection', function ($app) {
            return new Connection(config('riak'));
        });
    }
}

該服務提供者只定義了一個 register方法,并使用該方法在服務容器中定義了一個 Riak\Contracts\Connection的實現(xiàn)。如果你不太理解服務容器是怎么工作的,查看其文檔。

2.2 boot 方法

如果我們想要在服務提供者中注冊視圖 composer 該怎么做?這就要用到 boot方法了。該方法在所有服務提供者被注冊以后才會被調(diào)用,這就是說我們可以在其中訪問框架已注冊的所有其它服務:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('view', function () {
            //
        });
    }

    /**
     * 在容器中注冊綁定.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

2.2.1 boot 方法的依賴注入

我們可以在boot方法中類型提示依賴,服務容器會自動注冊你所需要的依賴:

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $factory){
    $factory->macro('caps', function ($value) {
        //
    });
}

3、注冊服務提供者

所有服務提供者都是通過配置文件 config/app.php中進行注冊,該文件包含了一個列出所有服務提供者名字的providers數(shù)組,默認情況下,其中列出了所有核心服務提供者,這些服務提供者啟動 Laravel 核心組件,比如郵件、隊列、緩存等等。

要注冊你自己的服務提供者,只需要將其加到該數(shù)組中即可:

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $factory){
    $factory->macro('caps', function ($value) {
        //
    });
}

4、延遲加載服務提供者

如果你的提供者僅僅只是在服務容器中注冊綁定,你可以選在延遲加載該綁定直到注冊綁定真的需要時再加載,延遲加載這樣的一個提供者將會提升應用的性能,因為它不會在每次請求時都從文件系統(tǒng)加載。

想要延遲加載一個提供者,設(shè)置 defer屬性為 true并定義一個 providers方法,該方法返回該提供者注冊的服務容器綁定:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider{
    /**
     * 服務提供者加是否延遲加載.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * 注冊服務提供者
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('Riak\Contracts\Connection', function ($app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * 獲取由提供者提供的服務.
     *
     * @return array
     */
    public function provides()
    {
        return ['Riak\Contracts\Connection'];
    }

}

Laravel 編譯并保存所有延遲服務提供者提供的服務及服務提供者的類名。然后,只有當你嘗試解析其中某個服務時 Laravel 才會加載其服務提供者。

上一篇:起步下一篇:應用目錄結(jié)構(gòu)