邊看文件邊翻譯邊理解…

本文大綱

Provider 基本概念

Service Provider 是所有 Laravel application 註冊服務的中心。 包含:

  1. registering service container bindings
  2. event listeners
  3. middleware
  4. router

config/app.php

php
  • php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'providers' => [
        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        Illuminate\Database\DatabaseServiceProvider::class,
        Illuminate\Encryption\EncryptionServiceProvider::class,
        Illuminate\Filesystem\FilesystemServiceProvider::class,
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
        Illuminate\Hashing\HashServiceProvider::class,
        Illuminate\Mail\MailServiceProvider::class,
        Illuminate\Notifications\NotificationServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
        Illuminate\Pipeline\PipelineServiceProvider::class,
        Illuminate\Queue\QueueServiceProvider::class,
        Illuminate\Redis\RedisServiceProvider::class,
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        Illuminate\Session\SessionServiceProvider::class,
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,

        /*
         * Package Service Providers...
         */

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

    ],
以上為 application 載入時,要 load 的 service provider,service 真正實際啟動時才會被 load。

編寫 service provider

所有 service provider extend Illuminate\Support\ServiceProvider,每個 service provider 都包含一個 register and boot method。在 register method 中,你只需要將 service bind 進去 service container。

AppServiceProvider.php
  • php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

namespace App\Providers;

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

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection(config('riak'));
        });
    }
}
不要將 event listeners, routes 或其他功能 bind service provider。 如果你的 Service Provider 註冊許多 bindings,可用 binds and singletons,去讓程式更有可讀性,在 load service provider 自動檢查這些屬性,register 相對應 bindings。

boot 做什麼用的呢? 其作為啟動所有 application service,其啟動於 all service providers are registered 才能被調用。

all service providers 透過 config/app.php 進行 register,包含郵件、queue、cache和其他功能。

Deferred Providers

可以選擇延遲 load 該綁定直到其服務真的需要時才去 load 其 providers,可增加應用性能,不會每次請求都 load。

Faceds

概念為 service container 提供一個 static interface 可使用於 service container。 Laravel Faceds 定義在 Illuminate\Support\Facades namespace 下。

use Illuminate\Support\Facades\Route;

Route::get('/cache', function () { return Cache::get(‘key’); });

Facades 不需要注入,但要小心別讓 class 越來越肥大,Facades 不同於 dependency injection,DI 在測試時,會 inject mock or stub 去 assert 結果。 Facades 不會是 mock or stub,Facades 就我閱讀起來比較像是全域的插件,可以隨時呼叫內建於 Laravel 的小功能。

總結與心得

我用一個比喻去描述我看完 Laravel container and service 的概念。
Service container 就像是水族箱的箱子一樣,你沒裝水,或安裝不同器具的功能,其就只是個箱子。
Service provider 像是安裝於的功能,你在使用這些功能前,必須檢查其有無安裝於此水族箱 (container) 內,才能呼叫使用這個水族箱的服務。
Facades 很像是 Laravel 內建寫好的小功能,就像水族箱原生就有過濾器,有點像是內建的魔法糖,其為全域都可呼叫。
基本的 Laravel 的核心架構文件大致上都看完了,接下來會挑重點去看 Laravel 的基礎功能。

參考連結