什麼是 Manager
Illuminate\Support\Manager 是自 Laravel 4.0 以來就存在的抽象類別。它提供簡易的基礎,用來建構可切換多個「Driver」使用的系統,例如 Cache、Session、Mail。
「Driver」是指擁有相同介面但內部實作不同的後端。舉例來說,Session 有 file、cookie、database、redis 等 Driver,可透過設定檔的 driver 鍵切換。
框架內的使用狀況
即便名稱含有Manager,仍有並未繼承 Illuminate\Support\Manager 的類別存在。
未繼承者,其「以
extend() 擴充」的基本觀念是相同的。因此理解 Manager 模式即等於理解框架整體運作。
基本機制
driver() — 取得 Driver
呼叫driver() 時,會依下列順序解析 Driver。
觀察實際原始碼可看到,從 Driver 名稱以 Str::studly() 組成方法名稱。
file Driver 會呼叫 createFileDriver(),my-custom Driver 則會呼叫 createMyCustomDriver()。
extend() — 註冊自訂 Driver
透過extend() 傳入 Driver 名稱與 closure,即可註冊自訂 Driver。closure 的引數為容器實例。
extend() 會將 closure 綁定至 $this,因此可在 closure 中存取 Manager 的屬性與方法。
__call — 委派至預設 Driver
Manager 類別實作了__call,Manager 本身不存在的方法呼叫會自動委派給預設 Driver。
SessionManager::get('key') 一樣直接使用 Manager,實際處理則交給 Driver」的流程。
SessionManager 的實作範例
觀察Illuminate\Session\SessionManager 可以具體了解 Manager 的使用方式。
於自製套件中使用 Manager
基本實作
以通知服務為例,建立繼承Manager 的自訂類別。
1
建立繼承 Manager 的類別
2
於服務提供者註冊
3
新增自訂 Driver
4
使用
MultipleInstanceManager
Illuminate\Support\MultipleInstanceManager 是 Laravel 10 新增的類別。相對於 Manager 管理 Driver 的「種類」,MultipleInstanceManager 可管理多個具名的「實例」。
與 Manager 的差異
必要方法
若要繼承MultipleInstanceManager,需實作 3 個方法。
getInstanceConfig() 回傳對應名稱的設定陣列。設定中必定要包含 driver(或以 $driverKey 指定的 key)。
解析流程
自製套件的實作範例
以同時對應多個 SMS Gateway 的套件為例。instance() 指定名稱。
Driver 快取的管理
Manager 的快取操作
MultipleInstanceManager 的快取操作
總結
Manager管理 Driver 的「種類」。實作createXxxDriver()方法,並以extend()擴充MultipleInstanceManager依名稱管理 Driver 的「實例」。適合需要多個連線設定的套件- 名為
Manager的類別並非全部繼承Illuminate\Support\Manager。CacheManager與QueueManager為自行實作
Macroable trait
學習為既有類別新增自訂方法的 Macroable trait 的用法。