Home » Code » Laravel文件系统

Laravel文件系统

Laravel 的文件系统可以定义不同的磁盘,不同磁盘可以使用不同驱动。

门面 Storage Illuminate\Support\Facades\Storage 返回的是 Illuminate\Filesystem\FilesystemManager 文件系统管理器,可以与不同的磁盘进行交互。常见方法:

  • extend($name, $closure), 扩展一个驱动
  • disk($name), 获得一个磁盘实例
  • driver($name), 获得一个驱动实例,实际也是调用 disk() 获得一个磁盘实例
  • 添加了 __call(), 可以直接调用默认磁盘的方法

磁盘实例 Illuminate\Contracts\Filesystem\Filesystem, 常见接口方法:

  • put($path, $contents),往磁盘里写文件
  • exists($path), 判断一个文件是否存在

实际上,获得磁盘实例的时候,返回的是文件系统适配器 Illuminate\Filesystem\FilesystemAdapter 的实例,文件系统适配器是实现了磁盘接口的。适配器中 driver 属性存储了该磁盘所用的驱动 League\Flysystem\FilesystemInterface,文件系统适配器中的方法都是通过直接或间接调用磁盘驱动器的方法来实现的,文件系统适配器中常用的方法:

  • putFile($path, $file),保存一个文件
  • putFileAs($path, $file, $name),以指定名称保存一个文件
  • url($path), 获取一个文件的 URL 地址。该方法不一定可用,当驱动有 getUrl() 方法, 或者驱动的适配器有 getUrl() 方法时,才可用。
  • 添加了 __call(), 直接调用驱动中的方法

我们自定义磁盘驱动时,需要一个实现了 League\Flysystem\FilesystemInterface 的类, 该包自带的类 League\Flysystem\Filesystem 已经实现之。但是要获得它的实例,又需要一个实现了 League\Flysystem\AdapterInterface 的类作为适配器。总结如下:

//驱动需要一个适配器
class myDriverAdapter implements League\Flysystem\AdapterInterface
{
    
}

//扩展驱动
Storage::extend('my-driver', function ($app, $config) {
    return new League\Flysystem\Filesystem(new myDriverAdapter);
})

在 Storage 上调用方法,跟在指定磁盘上 Storage::disk() 上调用,是一样的,只是前者会选择使用默认磁盘,实际都是调用文件系统适配器 Illuminate\Filesystem\FilesystemAdapter 中的方法,查找方法的顺序是:

文件系统适配器:Illuminate\Filesystem\FilesystemAdapter 
-> 磁盘驱动:League\Flysystem\Filesystem
-> 磁盘驱动适配器:myDriverAdapter implements League\Flysystem\AdapterInterface
-> 磁盘驱动扩展:League\Flysystem\PluginInterface

最近我写了一个国外网盘 cloudinary 的磁盘驱动,实现 League\Flysystem\AdapterInterface 的磁盘适配器已经有人写了,但是它没有 getUrl() 方法,因此 Storage::url() 是不可用的。我在它的基础上添加了 getUrl() 方法,这样就可以放心的适用在 Laravel 中了,尤其是 Laravel admin 源码中已经用了 Storage::url() 方法,现成的包基本找不到,只有自己动手了。地址:https://github.com/xiaomlove/laravel-filesystem-cloudinary

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.