什么是 Manager
Illuminate\Support\Manager 是从 Laravel 4.0 时代就存在的抽象类。它为缓存、Session、Mail 等能切换多个「驱动」的系统提供了简洁的构建基础。
「驱动」是指具有相同接口但内部实现不同的后端。例如 Session 有 file、cookie、database、redis 等驱动,可通过配置文件的 driver 键切换。
框架内的使用情况
以Manager 命名的类并非都继承自 Illuminate\Support\Manager。
即使未继承,用
extend() 扩展的基本思路也一致。因此理解 Manager 模式有助于把握整个框架的运作。
基本机制
driver() — 获取驱动
调用driver() 后,驱动按下面的流程解析:
查看实际源码可以看到,它是用 Str::studly() 将驱动名拼出方法名。
file 驱动调用 createFileDriver(),my-custom 驱动则调用 createMyCustomDriver()。
extend() — 注册自定义驱动
将驱动名与闭包传给extend(),可以注册自定义驱动。闭包参数是容器实例。
extend() 会把闭包绑定到 $this,因此在闭包中可以访问 Manager 的属性与方法。
__call — 委托到默认驱动
Manager 类实现了__call,Manager 本身不存在的方法调用会自动委托给默认驱动。
SessionManager::get('key') 一样直接使用 Manager,实际处理则交给驱动。
SessionManager 实现示例
看看Illuminate\Session\SessionManager,可以具体了解 Manager 的用法。
在自定义包中使用 Manager
基本实现
以通知服务为例,构建一个继承Manager 的类。
1
创建继承 Manager 的类
2
在 Service Provider 中注册
3
添加自定义驱动
4
使用
MultipleInstanceManager
Illuminate\Support\MultipleInstanceManager 是 Laravel 10 中新增的类。Manager 管理的是「驱动种类」,而 MultipleInstanceManager 可以管理多个具名的「实例」。
与 Manager 的区别
必需方法
继承MultipleInstanceManager 时需要实现 3 个方法。
getInstanceConfig() 返回对应名字的配置数组。配置中必须包含 driver(或 $driverKey 指定的键)。
解析流程
自定义包的实现示例
以同时对接多个 SMS 网关的包为例。instance() 指定名字。
驱动缓存管理
Manager 的缓存操作
MultipleInstanceManager 的缓存操作
小结
Manager管理驱动的「种类」。实现createXxxDriver()方法,用extend()扩展MultipleInstanceManager按名字管理驱动的「实例」,适合需要多连接配置的包- 名字里带
Manager的类并不一定都继承自Illuminate\Support\Manager。CacheManager和QueueManager都是自实现
Macroable trait
学习向既有类添加自定义方法的 Macroable trait。