ThinkPHP的 Filesystem(文件系统)

226 阅读3分钟

ThinkPHP 的 Filesystem(文件系统)组件提供了统一的接口来操作不同的文件存储系统,如本地文件系统、云存储等。以下是关于 ThinkPHP Filesystem 的详细介绍:

配置

  • 定义磁盘:在 ThinkPHP 中,文件系统的配置文件通常是config/filesystem.php。在该文件中,可以定义不同的磁盘(存储位置)及其相关配置。例如,定义一个本地磁盘和一个阿里云 OSS 磁盘:

return [
    // 默认磁盘
    'default' => env('filesystem.driver', 'local'),

    // 磁盘配置
    'disks'   => [
        'local' => [
            // 磁盘驱动
            'driver' => 'local',
            // 根目录
            'root'   => app()->getRootPath().'public/storage',
        ],
        'oss' => [
            'driver' => 'oss',
            'accessKeyId' => 'your-access-key-id',
            'accessKeySecret' => 'your-access-key-secret',
            'endpoint' => 'your-endpoint',
            'bucket' => 'your-bucket-name',
        ],
    ],
];
  • 环境变量配置:为了方便在不同环境中切换文件系统配置,可以使用环境变量。例如,在.env文件中设置FILESYSTEM_DRIVER=localFILESYSTEM_DRIVER=oss来指定默认使用的磁盘。

使用方法

  • 上传文件

    • 单个文件上传:在控制器中,可以使用request()->file()方法获取上传的文件,然后使用Storage门面的putFileputFileAs方法将文件保存到指定磁盘。例如:

use think\facade\Storage;

public function upload()
{
    // 获取上传的文件
    $file = request()->file('file');
    if ($file) {
        // 将文件保存到本地磁盘的uploads目录,并获取保存后的文件名
        $fileName = Storage::disk('local')->putFile('uploads', $file);
        if ($fileName) {
            return '文件上传成功,文件名:'.$fileName;
        } else {
            return '文件上传失败';
        }
    } else {
        return '请选择要上传的文件';
    }
}
  • 多个文件上传:如果要上传多个文件,可以使用循环来处理。例如:

use think\facade\Storage;

public function uploadMultiple()
{
    // 获取上传的多个文件
    $files = request()->file('files');
    if ($files) {
        $uploadedFiles = [];
        foreach ($files as $file) {
            // 将文件保存到本地磁盘的uploads目录,并获取保存后的文件名
            $fileName = Storage::disk('local')->putFile('uploads', $file);
            if ($fileName) {
                $uploadedFiles[] = $fileName;
            }
        }
        if (!empty($uploadedFiles)) {
            return '文件上传成功,文件名:'.implode(', ', $uploadedFiles);
        } else {
            return '文件上传失败';
        }
    } else {
        return '请选择要上传的文件';
    }
}
  • 下载文件:可以使用Storage门面的download方法来实现文件下载。例如:

use think\facade\Storage;

public function download($fileName)
{
    // 从本地磁盘下载文件
    return Storage::disk('local')->download('uploads/'.$fileName);
}
  • 删除文件:使用Storage门面的delete方法可以删除指定磁盘上的文件。例如:

use think\facade\Storage;

public function deleteFile($fileName)
{
    // 删除本地磁盘上的文件
    if (Storage::disk('local')->delete('uploads/'.$fileName)) {
        return '文件删除成功';
    } else {
        return '文件删除失败';
    }
}
  • 文件信息获取:可以使用Storage门面的exists方法检查文件是否存在,使用size方法获取文件大小,使用lastModified方法获取文件的最后修改时间等。例如:

use think\facade\Storage;

public function fileInfo($fileName)
{
    // 检查文件是否存在
    $exists = Storage::disk('local')->exists('uploads/'.$fileName);
    // 获取文件大小
    $size = Storage::disk('local')->size('uploads/'.$fileName);
    // 获取文件最后修改时间
    $lastModified = Storage::disk('local')->lastModified('uploads/'.$fileName);

    return '文件是否存在:'.($exists? '是' : '否').', 文件大小:'.$size.', 最后修改时间:'.date('Y-m-d H:i:s', $lastModified);
}

自定义驱动

  • 创建自定义驱动类:如果需要使用 ThinkPHP 默认不支持的文件存储系统,可以创建自定义的文件系统驱动类。首先,创建一个驱动类,实现League\Flysystem\FilesystemAdapter接口。例如:

<?php

namespace app\filesystem\driver;

use League\Flysystem\FilesystemAdapter;
use League\Flysystem\Config;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemException;
use League\Flysystem\UnableToCopyFile;
use League\Flysystem\UnableToCreateDirectory;
use League\Flysystem\UnableToDeleteDirectory;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToReadFile;
use League\Flysystem\UnableToRetrieveMetadata;
use League\Flysystem\UnableToWriteFile;

class CustomDriver implements FilesystemAdapter
{
    // 实现接口中的方法,如文件读取、写入、删除等操作
    public function write(string $path, string $contents, Config $config): void
    {
        // 自定义的写入文件逻辑
    }

    // 其他方法的实现...
}
  • 注册驱动:然后,在filesystem.php配置文件中注册自定义驱动:

return [
    // 默认磁盘
    'default' => env('filesystem.driver', 'local'),

    // 磁盘配置
    'disks'   => [
        'local' => [
            'driver' => 'local',
            'root'   => app()->getRootPath().'public/storage',
        ],
        'custom' => [
            'driver' => \app\filesystem\driver\CustomDriver::class,
            // 自定义驱动的其他配置参数
            'param1' => 'value1',
            'param2' => 'value2',
        ],
    ],
];

通过 Filesystem 组件,ThinkPHP 提供了一种方便、灵活的方式来管理文件存储,无论是本地文件还是远程云存储,都能以统一的接口进行操作,提高了代码的可维护性和可扩展性。