翻译进度
15
分块数量
1
参与人数

文件存储

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


文件存储

介绍

Laravel 借助 Frank de Jonge 开发的优秀 PHP 包 Flysystem,提供了一套强大的文件系统抽象层。
Laravel 对 Flysystem 的集成,为本地文件系统、SFTP 和 Amazon S3 提供了简单易用的驱动。
更方便的是,你可以非常轻松地在本地开发环境和生产服务器之间切换不同的存储方式,因为每种存储系统使用的 API 都是相同的。

配置

Laravel 的文件系统配置文件位于 config/filesystems.php。
在这个文件中,你可以配置应用程序使用的所有文件系统“磁盘(disk)”。每个磁盘都代表一种特定的存储驱动和存储位置。
配置文件中已经包含了每种受支持驱动的示例配置,你可以根据自己的存储需求和认证凭据修改这些配置。
local 驱动用于操作存储在运行 Laravel 应用程序的服务器本地文件。
sftp 存储驱动用于通过基于 SSH 密钥的 FTP 方式进行文件存储。
s3 驱动用于将文件写入 Amazon S3 云存储服务。

[!注意]
你可以根据需要配置任意数量的磁盘,并且也可以配置多个使用相同驱动的磁盘。

无与伦比 翻译于 4天前

本地驱动

使用 local 驱动时,所有文件操作都会相对于 filesystems 配置文件中定义的 root 目录进行。默认情况下,该值被设置为 storage/app/private 目录。因此,下面的方法会将文件写入 storage/app/private/example.txt:

use Illuminate\Support\Facades\Storage;

Storage::disk('local')->put('example.txt', 'Contents');

公共磁盘

应用程序 filesystems 配置文件中包含的 public 磁盘,主要用于存储需要公开访问的文件。
默认情况下,public 磁盘使用 local 驱动,并将文件存储在 storage/app/public 目录中。

如果你的 public 磁盘使用的是 local 驱动,并且你希望这些文件可以通过 Web 访问,那么你应该创建一个符号链接,将源目录 storage/app/public 链接到目标目录 public/storage:
要创建这个符号链接,可以使用 storage:link Artisan 命令:

php artisan storage:link

文件存储完成并创建好符号链接后,你可以使用 asset 辅助函数生成这些文件的 URL:

echo asset('storage/file.txt');

你也可以在 filesystems 配置文件中配置额外的符号链接。
运行 storage:link 命令时,所有已配置的链接都会被创建:

'links' => [
    public_path('storage') => storage_path('app/public'),
    public_path('images') => storage_path('app/images'),
],

可以使用 storage:unlink 命令删除你配置的符号链接:

php artisan storage:unlink
无与伦比 翻译于 4天前

驱动前置条件

S3 驱动配置

在使用 S3 驱动之前,你需要通过 Composer 包管理器安装 Flysystem 的 S3 扩展包:

composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies

S3 磁盘的配置数组位于 config/filesystems.php 配置文件中。
通常,你应该使用以下环境变量来配置 S3 相关信息和凭据,这些环境变量会被 config/filesystems.php 配置文件引用:

AWS_ACCESS_KEY_ID=<your-key-id>
AWS_SECRET_ACCESS_KEY=<your-secret-access-key>
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=<your-bucket-name>
AWS_USE_PATH_STYLE_ENDPOINT=false

为了方便使用,这些环境变量的命名方式与 AWS CLI 使用的命名规范保持一致。

FTP 驱动配置

在使用 FTP 驱动之前,你需要通过 Composer 包管理器安装 Flysystem 的 FTP 扩展包:

composer require league/flysystem-ftp "^3.0"

Laravel 的 Flysystem 集成可以很好地支持 FTP。不过,框架默认的 config/filesystems.php 配置文件中并没有包含 FTP 的示例配置。如果你需要配置 FTP 文件系统,可以参考下面的配置示例:

'ftp' => [
    'driver' => 'ftp',
    'host' => env('FTP_HOST'),
    'username' => env('FTP_USERNAME'),
    'password' => env('FTP_PASSWORD'),

    // Optional FTP Settings...
    // 'port' => env('FTP_PORT', 21),
    // 'root' => env('FTP_ROOT'),
    // 'passive' => true,
    // 'ssl' => true,
    // 'timeout' => 30,
],

SFTP 驱动配置

在使用 SFTP 驱动之前,你需要通过 Composer 包管理器安装 Flysystem 的 SFTP 扩展包:

composer require league/flysystem-sftp-v3 "^3.0"

Laravel 的 Flysystem 集成可以很好地支持 SFTP。不过,框架默认的 config/filesystems.php 配置文件中并没有包含 SFTP 的示例配置。如果你需要配置 SFTP 文件系统,可以参考下面的配置示例:

'sftp' => [
    'driver' => 'sftp',
    'host' => env('SFTP_HOST'),

    // 基础身份认证配置...
    'username' => env('SFTP_USERNAME'),
    'password' => env('SFTP_PASSWORD'),

    // 使用带加密密码的 SSH 私钥进行身份认证...
    'privateKey' => env('SFTP_PRIVATE_KEY'),
    'passphrase' => env('SFTP_PASSPHRASE'),

    // 文件 / 目录权限配置...
    'visibility' => 'private', // `private` = 0600, `public` = 0644
    'directory_visibility' => 'private', // `private` = 0700, `public` = 0755

    // 可选的 SFTP 配置...
    // 'hostFingerprint' => env('SFTP_HOST_FINGERPRINT'),
    // 'maxTries' => 4,
    // 'passphrase' => env('SFTP_PASSPHRASE'),
    // 'port' => env('SFTP_PORT', 22),
    // 'root' => env('SFTP_ROOT', ''),
    // 'timeout' => 30,
    // 'useAgent' => true,
],
无与伦比 翻译于 4天前

限定范围和只读文件系统

限定范围的磁盘允许你定义一个文件系统,在这个文件系统中,所有路径都会自动添加指定的路径前缀。
在创建限定范围的文件系统磁盘之前,你需要通过 Composer 包管理器安装一个额外的 Flysystem 扩展包:

composer require league/flysystem-path-prefixing "^3.0"

你可以通过定义一个使用 scoped 驱动的磁盘,为任何现有的文件系统磁盘创建一个限定路径范围的实例。
例如,你可以创建一个磁盘,将现有的 s3 磁盘限定到某个特定的路径前缀。之后,所有通过该限定范围磁盘执行的文件操作,都会自动使用指定的前缀:

's3-videos' => [
    'driver' => 'scoped',
    'disk' => 's3',
    'prefix' => 'path/to/videos',
],

“只读”磁盘允许你创建禁止执行写入操作的文件系统磁盘。
在使用 read-only 配置选项之前,你需要通过 Composer 包管理器安装一个额外的 Flysystem 扩展包:

composer require league/flysystem-read-only "^3.0"

接下来,你可以在一个或多个磁盘的配置数组中加入 read-only 配置选项:

's3-videos' => [
    'driver' => 's3',
    // ...
    'read-only' => true,
],

兼容 Amazon S3 的文件系统

默认情况下,应用程序的 filesystems 配置文件中已经包含了 s3 磁盘的配置。
除了可以使用该磁盘与 Amazon S3 交互之外,你还可以使用它来连接任何兼容 S3 的文件存储服务,例如 RustFS、DigitalOcean Spaces、Vultr Object Storage、Cloudflare R2 或 Hetzner Cloud Storage。

无与伦比 翻译于 4天前

通常,在将磁盘的访问凭据更新为你计划使用的存储服务所对应的凭据后,你只需要修改 endpoint 配置项的值。
该配置项通常通过 AWS_ENDPOINT 环境变量来定义:

'endpoint' => env('AWS_ENDPOINT', 'https://rustfs:9000'),

获取磁盘实例

你可以使用 Storage facade 与任何已配置的磁盘进行交互。
例如,你可以调用 facade 的 put 方法,将头像文件存储到默认磁盘中。
如果你没有先调用 disk 方法,而是直接调用 Storage facade 上的方法,那么该方法会自动作用于默认磁盘:

use Illuminate\Support\Facades\Storage;

Storage::put('avatars/1', $content);

如果你的应用程序需要操作多个磁盘,可以使用 Storage facade 的 disk 方法,指定要操作的磁盘:

Storage::disk('s3')->put('avatars/1', $content);

按需磁盘

有时,你可能希望在运行时根据指定配置创建一个磁盘,而不需要提前将该配置写入应用程序的 filesystems 配置文件中。
要实现这一点,可以将一个配置数组传递给 Storage facade 的 build 方法:

use Illuminate\Support\Facades\Storage;

$disk = Storage::build([
    'driver' => 'local',
    'root' => '/path/to/root',
]);

$disk->put('image.jpg', $content);

获取文件

可以使用 get 方法获取文件内容。该方法会返回文件的原始字符串内容。
请记住,所有文件路径都应该相对于磁盘的“根目录(root)”来指定:

$contents = Storage::get('file.jpg');
无与伦比 翻译于 4天前

如果你要获取的文件包含 JSON 数据,可以使用 json 方法读取文件并自动解码其中的内容:

$orders = Storage::json('orders.json');

可以使用 exists 方法判断磁盘中是否存在某个文件:

if (Storage::disk('s3')->exists('file.jpg')) {
    // ...
}

可以使用 missing 方法判断磁盘中是否缺少某个文件:

if (Storage::disk('s3')->missing('file.jpg')) {
    // ...
}

下载文件

可以使用 download 方法生成一个响应,强制用户的浏览器下载指定路径的文件。download 方法的第二个参数可以指定下载时用户看到的文件名。此外,还可以通过第三个参数传入 HTTP 响应头数组:

return Storage::download('file.jpg');

return Storage::download('file.jpg', $name, $headers);

文件 URL

可以使用 url 方法获取指定文件的 URL。如果使用的是 local 驱动,Laravel 通常会在给定路径前添加 /storage,并返回该文件的相对 URL。如果使用的是 s3 驱动,则会返回完整的远程 URL:

use Illuminate\Support\Facades\Storage;

$url = Storage::url('file.jpg');

使用 local 驱动时,所有需要公开访问的文件都应该存放在 storage/app/public 目录中。
此外,你还应该在 public/storage 创建一个指向 storage/app/public 目录的符号链接。

[!警告]
使用 local 驱动时,url 方法返回的值不会进行 URL 编码。因此,我们建议始终使用能够生成有效 URL 的文件名来存储文件。

无与伦比 翻译于 3天前

自定义 URL 主机地址

如果你希望修改通过 Storage facade 生成的 URL 主机地址,可以在磁盘的配置数组中添加或修改 url 配置项:

'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
    'throw' => false,
],

临时 URL

使用 temporaryUrl 方法,可以为通过 local 和 s3 驱动存储的文件创建临时 URL。
该方法接收一个文件路径,以及一个用于指定 URL 过期时间的 DateTime 实例:

use Illuminate\Support\Facades\Storage;

$url = Storage::temporaryUrl(
    'file.jpg', now()->plus(minutes: 5)
);

启用本地临时 URL

如果你的应用是在 local 驱动支持临时 URL 之前开始开发的,那么你可能需要手动启用本地临时 URL。为此,可以在 config/filesystems.php 配置文件中的 local 磁盘配置数组里添加 serve 选项:

'local' => [
    'driver' => 'local',
    'root' => storage_path('app/private'),
    'serve' => true, // [tl! add]
    'throw' => false,
],

S3 请求参数

如果你需要指定额外的 S3 请求参数,可以将请求参数数组作为 temporaryUrl 方法的第三个参数传入:

$url = Storage::temporaryUrl(
    'file.jpg',
    now()->plus(minutes: 5),
    [
        'ResponseContentType' => 'application/octet-stream',
        'ResponseContentDisposition' => 'attachment; filename=file2.jpg',
    ]
);

自定义临时 URL

如果你需要自定义某个存储磁盘生成临时 URL 的方式,可以使用 buildTemporaryUrlsUsing 方法。例如,如果你有一个控制器,用于下载某个通常不支持临时 URL 的磁盘中存储的文件,那么这个方法就非常有用。通常情况下,这个方法应该在服务提供者的 boot 方法中调用:

<?php

namespace App\Providers;

use DateTime;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 启动应用程序服务。
     */
    public function boot(): void
    {
        Storage::disk('local')->buildTemporaryUrlsUsing(
            function (string $path, DateTime $expiration, array $options) {
                return URL::temporarySignedRoute(
                    'files.download',
                    $expiration,
                    array_merge($options, ['path' => $path])
                );
            }
        );
    }
}
无与伦比 翻译于 3天前

临时上传 URL

[!警告]
生成临时上传 URL 的功能仅支持 s3 和 local 驱动。

如果你需要生成一个临时 URL,让客户端应用可以直接上传文件,可以使用 temporaryUploadUrl 方法。该方法接收一个文件路径,以及一个用于指定 URL 过期时间的 DateTime 实例。
temporaryUploadUrl 方法会返回一个关联数组,你可以将其解构为上传 URL,以及上传请求中需要携带的请求头:

use Illuminate\Support\Facades\Storage;

['url' => $url, 'headers' => $headers] = Storage::temporaryUploadUrl(
    'file.jpg', now()->plus(minutes: 5)
);

这个方法主要适用于 Serverless 环境,在这类环境中,通常需要客户端应用直接将文件上传到 Amazon S3 等云存储系统。

文件元数据

除了读取和写入文件之外,Laravel 还可以提供文件本身的相关信息。例如,可以使用 size 方法获取文件大小,单位为字节:

use Illuminate\Support\Facades\Storage;

$size = Storage::size('file.jpg');

lastModified 方法会返回文件最后一次修改时间对应的 UNIX 时间戳:

$time = Storage::lastModified('file.jpg');

可以通过 mimeType 方法获取指定文件的 MIME 类型:

$mime = Storage::mimeType('file.jpg');

文件路径

可以使用 path 方法获取指定文件的路径。如果使用的是 local 驱动,该方法会返回文件的绝对路径。如果使用的是 s3 驱动,该方法会返回文件在 S3 Bucket 中的相对路径:

use Illuminate\Support\Facades\Storage;

$path = Storage::path('file.jpg');
无与伦比 翻译于 3天前

存储文件

可以使用 put 方法将文件内容存储到磁盘中。你也可以将 PHP resource 传递给 put 方法,此时会使用 Flysystem 底层的流式处理支持。请记住,所有文件路径都应该相对于磁盘配置中的 root 目录来指定:

use Illuminate\Support\Facades\Storage;

Storage::put('file.jpg', $contents);

Storage::put('file.jpg', $resource);

写入失败

如果 put 方法(或其他“写入”操作)无法将文件写入磁盘,则会返回 false:

if (! Storage::put('file.jpg', $contents)) {
    // 文件无法写入磁盘...
}

如果你愿意,也可以在文件系统磁盘的配置数组中定义 throw 选项。当该选项设置为 true 时,像 put 这样的“写入”方法在写入失败时,会抛出一个 League\Flysystem\UnableToWriteFile 异常实例:

'public' => [
    'driver' => 'local',
    // ...
    'throw' => true,
],

在文件前面和后面追加内容

prepend 和 append 方法允许你分别向文件的开头或末尾写入内容:

Storage::prepend('file.log', 'Prepended Text');

Storage::append('file.log', 'Appended Text');

复制和移动文件

可以使用 copy 方法将现有文件复制到磁盘中的新位置。可以使用 move 方法对现有文件进行重命名,或者将其移动到新的位置:

Storage::copy('old/file.jpg', 'new/file.jpg');

Storage::move('old/file.jpg', 'new/file.jpg');
无与伦比 翻译于 3天前

自动流式传输

将文件以流的方式写入存储可以显著减少内存占用。如果你希望 Laravel 自动管理文件的流式写入,可以使用 putFile 或 putFileAs 方法。这两个方法都可以接收一个 Illuminate\Http\File 或 Illuminate\Http\UploadedFile 实例,并自动以流的方式将文件写入指定位置:

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// 自动生成唯一文件名...
$path = Storage::putFile('photos', new File('/path/to/photo'));

// 手动指定文件名...
$path = Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

关于 putFile 方法,有几个重要事项需要注意。这里我们只指定了目录名,并没有指定文件名。默认情况下,putFile 方法会自动生成一个唯一 ID 作为文件名。文件扩展名会根据文件的 MIME 类型自动确定。putFile 方法会返回文件路径,因此你可以将这个路径(包括自动生成的文件名)保存到数据库中。putFile 和 putFileAs 方法还可以接收一个参数,用来指定所存储文件的“可见性”。
当你将文件存储到 Amazon S3 之类的云磁盘,并希望文件可以通过生成的 URL 公开访问时,这个功能尤其有用:

Storage::putFile('photos', new File('/path/to/photo'), 'public');

文件上传

在 Web 应用中,文件存储最常见的使用场景之一,就是保存用户上传的文件,例如图片和文档Laravel 通过上传文件实例上的 store 方法,让保存上传文件变得非常简单。调用 store 方法时,只需要传入你希望保存上传文件的路径:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserAvatarController extends Controller
{
    /**
     * 更新用户头像。
     */
    public function update(Request $request): string
    {
        $path = $request->file('avatar')->store('avatars');

        return $path;
    }
}
无与伦比 翻译于 3天前

There are a few important things to note about this example. Note that we only specified a directory name, not a filename. By default, the store method will generate a unique ID to serve as the filename. The file's extension will be determined by examining the file's MIME type. The path to the file will be returned by the store method so you can store the path, including the generated filename, in your database.

You may also call the putFile method on the Storage facade to perform the same file storage operation as the example above:

$path = Storage::putFile('avatars', $request->file('avatar'));

Specifying a File Name

If you do not want a filename to be automatically assigned to your stored file, you may use the storeAs method, which receives the path, the filename, and the (optional) disk as its arguments:

$path = $request->file('avatar')->storeAs(
    'avatars', $request->user()->id
);

You may also use the putFileAs method on the Storage facade, which will perform the same file storage operation as the example above:

$path = Storage::putFileAs(
    'avatars', $request->file('avatar'), $request->user()->id
);

[!WARNING]
Unprintable and invalid unicode characters will automatically be removed from file paths. Therefore, you may wish to sanitize your file paths before passing them to Laravel's file storage methods. File paths are normalized using the League\Flysystem\WhitespacePathNormalizer::normalizePath method.

Specifying a Disk

By default, this uploaded file's store method will use your default disk. If you would like to specify another disk, pass the disk name as the second argument to the store method:

$path = $request->file('avatar')->store(
    'avatars/'.$request->user()->id, 's3'
);

If you are using the storeAs method, you may pass the disk name as the third argument to the method:

$path = $request->file('avatar')->storeAs(
    'avatars',
    $request->user()->id,
    's3'
);

Other Uploaded File Information

If you would like to get the original name and extension of the uploaded file, you may do so using the getClientOriginalName and getClientOriginalExtension methods:

$file = $request->file('avatar');

$name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();

However, keep in mind that the getClientOriginalName and getClientOriginalExtension methods are considered unsafe, as the file name and extension may be tampered with by a malicious user. For this reason, you should typically prefer the hashName and extension methods to get a name and an extension for the given file upload:

$file = $request->file('avatar');

$name = $file->hashName(); // Generate a unique, random name...
$extension = $file->extension(); // Determine the file's extension based on the file's MIME type...

File Visibility

In Laravel's Flysystem integration, "visibility" is an abstraction of file permissions across multiple platforms. Files may either be declared public or private. When a file is declared public, you are indicating that the file should generally be accessible to others. For example, when using the S3 driver, you may retrieve URLs for public files.

You can set the visibility when writing the file via the put method:

use Illuminate\Support\Facades\Storage;

Storage::put('file.jpg', $contents, 'public');

If the file has already been stored, its visibility can be retrieved and set via the getVisibility and setVisibility methods:

$visibility = Storage::getVisibility('file.jpg');

Storage::setVisibility('file.jpg', 'public');

When interacting with uploaded files, you may use the storePublicly and storePubliclyAs methods to store the uploaded file with public visibility:

$path = $request->file('avatar')->storePublicly('avatars', 's3');

$path = $request->file('avatar')->storePubliclyAs(
    'avatars',
    $request->user()->id,
    's3'
);

Local Files and Visibility

When using the local driver, public visibility translates to 0755 permissions for directories and 0644 permissions for files. You can modify the permissions mappings in your application's filesystems configuration file:

'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
    'permissions' => [
        'file' => [
            'public' => 0644,
            'private' => 0600,
        ],
        'dir' => [
            'public' => 0755,
            'private' => 0700,
        ],
    ],
    'throw' => false,
],

Deleting Files

The delete method accepts a single filename or an array of files to delete:

use Illuminate\Support\Facades\Storage;

Storage::delete('file.jpg');

Storage::delete(['file.jpg', 'file2.jpg']);

If necessary, you may specify the disk that the file should be deleted from:

use Illuminate\Support\Facades\Storage;

Storage::disk('s3')->delete('path/file.jpg');

Directories

Get All Files Within a Directory

The files method returns an array of all files within a given directory. If you would like to retrieve a list of all files within a given directory including subdirectories, you may use the allFiles method:

use Illuminate\Support\Facades\Storage;

$files = Storage::files($directory);

$files = Storage::allFiles($directory);

Get All Directories Within a Directory

The directories method returns an array of all directories within a given directory. If you would like to retrieve a list of all directories within a given directory including subdirectories, you may use the allDirectories method:

$directories = Storage::directories($directory);

$directories = Storage::allDirectories($directory);

Create a Directory

The makeDirectory method will create the given directory, including any needed subdirectories:

Storage::makeDirectory($directory);

Delete a Directory

Finally, the deleteDirectory method may be used to remove a directory and all of its files:

Storage::deleteDirectory($directory);

Testing

The Storage facade's fake method allows you to easily generate a fake disk that, combined with the file generation utilities of the Illuminate\Http\UploadedFile class, greatly simplifies the testing of file uploads. For example:

<?php

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

test('albums can be uploaded', function () {
    Storage::fake('photos');

    $response = $this->json('POST', '/photos', [
        UploadedFile::fake()->image('photo1.jpg'),
        UploadedFile::fake()->image('photo2.jpg')
    ]);

    // Assert one or more files were stored...
    Storage::disk('photos')->assertExists('photo1.jpg');
    Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);

    // Assert one or more files were not stored...
    Storage::disk('photos')->assertMissing('missing.jpg');
    Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);

    // Assert that the number of files in a given directory matches the expected count...
    Storage::disk('photos')->assertCount('/wallpapers', 2);

    // Assert that a given directory is empty...
    Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
});
<?php

namespace Tests\Feature;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_albums_can_be_uploaded(): void
    {
        Storage::fake('photos');

        $response = $this->json('POST', '/photos', [
            UploadedFile::fake()->image('photo1.jpg'),
            UploadedFile::fake()->image('photo2.jpg')
        ]);

        // Assert one or more files were stored...
        Storage::disk('photos')->assertExists('photo1.jpg');
        Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);

        // Assert one or more files were not stored...
        Storage::disk('photos')->assertMissing('missing.jpg');
        Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);

        // Assert that the number of files in a given directory matches the expected count...
        Storage::disk('photos')->assertCount('/wallpapers', 2);

        // Assert that a given directory is empty...
        Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
    }
}

By default, the fake method will delete all files in its temporary directory. If you would like to keep these files, you may use the "persistentFake" method instead. For more information on testing file uploads, you may consult the HTTP testing documentation's information on file uploads.

[!WARNING]
The image method requires the GD extension.

Custom Filesystems

Laravel's Flysystem integration provides support for several "drivers" out of the box; however, Flysystem is not limited to these and has adapters for many other storage systems. You can create a custom driver if you want to use one of these additional adapters in your Laravel application.

In order to define a custom filesystem you will need a Flysystem adapter. Let's add a community maintained Dropbox adapter to our project:

composer require spatie/flysystem-dropbox

Next, you can register the driver within the boot method of one of your application's service providers. To accomplish this, you should use the extend method of the Storage facade:

<?php

namespace App\Providers;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        // ...
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Storage::extend('dropbox', function (Application $app, array $config) {
            $adapter = new DropboxAdapter(new DropboxClient(
                $config['authorization_token']
            ));

            return new FilesystemAdapter(
                new Filesystem($adapter, $config),
                $adapter,
                $config
            );
        });
    }
}

The first argument of the extend method is the name of the driver and the second is a closure that receives the $app and $config variables. The closure must return an instance of Illuminate\Filesystem\FilesystemAdapter. The $config variable contains the values defined in config/filesystems.php for the specified disk.

Once you have created and registered the extension's service provider, you may use the dropbox driver in your config/filesystems.php configuration file.

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~