之前写过一篇文章来讲 laravel
中的文件系统,提到框架中使用到两套文件系统,一套是 NativeFilesystem
,主要用于框架内部一些用到文件管理的场景,比如:生成缓存文件、生成模板文件、操作扩展包的文件等。另外一套是 Flysystem
基于 league/flysystem
扩展,提供对本地文件系统、FTP
、云盘等具备文件存储功能的系统的操作。也就是使用文档中的 Storage
。
Storage
面向更广泛、更普遍、更严格的文件管理的场景,所以逻辑也更为严谨与复杂。框架对 Storage
的封装有四个层次,每层解决不同的问题,各层都起到承上启下的作用,他们分别是:
Storage
: 最上层的对用户友好的操作接口,语义化程度较高。FilesystemAdapter
: 对文件系统的高级抽象,包含一定的使用场景原语,是对文件系统的运用范围的一定程度的扩展。Filesystem
: 统一文件管理的公共接口,而不需要关心文件最终会存储到什么地方,这一层已经回归到对文件的管理,这一单一职责上。Adapter
: 承接具体的文件管理职责,这里明确文件的存储方式,能对外提供的接口。
在了解到框架 Storage
的具体实现逻辑后,再来谈谈为什么我们要了解这些。在我负责的美术相关业务系统中,有大量的文件存储的需求,原本是单独部署的一个存储服务器,挂载到 web
服务器,统一保存这些文件资源。 后来 IT
部门对外采购了云存储服务,用来统一存储公司各个业务部门的业务文件,刚好我们系统也可以接入。由于前期的架构,代码中大量使用 Storage
的 local
驱动管理文件,而在接入云盘的过程中,需要实现新的驱动,来取代原始的 local
驱动。由此,在了解到框架对 Storage
的封装,以及云供应商提供的接口文档后,开始着手实现云存储的驱动。
在了解框架实现之后,很容易做出判断,在原有应用场景不变的情况下,可以跳过对 Storage
前三层的修改,直接在第四层 Adapter
进行封装,而这一层的主要职责,是对接统一的文件管理接口与云供应商提供的接口。具体需要实现的接口类是 League\Flysystem\AdapterInterface
:
1 |
|
考虑到后期可能对文件管理行为添加权限等场景,决定在 Adapter
下层再添加一层对云供应商接口的封装,其主要职责是对接 AdapterInterface
以及预留后期可能需要实现的功能接口。到此,就可以规划各层级的职责,建立基础的代码框架。
1 | /** |
代码开发完毕后,配置好云存储的参数,就可以开始使用,使用方面也可以区分两个层级。第一层级是以 Storage
完成对文件管理的操作,第二层级是以服务注入的方式,调用云供应商提供的原生接口,以次来实现存储功能外的需求。
1 | // 1. 作为 Storage 的云盘驱动使用 |
CloudDriverHandler::class/CloudAdapter::class
的具体实现如下:
1 |
|
1 |
|