Laravel 13 文件存储详解

摘要

Laravel 提供了强大的文件存储系统,支持本地存储和云服务。本文将深入讲解 Laravel 13 的文件存储功能,包括:

  • 文件系统配置
  • 本地与云存储
  • 文件上传处理
  • 文件操作与管理
  • 实战案例与最佳实践

本文适合希望掌握文件存储功能的 Laravel 开发者。

1. 配置

1.1 默认配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// config/filesystems.php
'default' => env('FILESYSTEM_DISK', 'local'),

'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'throw' => false,
],

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

's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],

1.2 创建符号链接

1
php artisan storage:link

2. 文件操作

2.1 基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Illuminate\Support\Facades\Storage;

// 读取文件
$content = Storage::get('file.txt');

// 写入文件
Storage::put('file.txt', 'Content');

// 追加内容
Storage::append('file.txt', 'Appended content');

// 前置内容
Storage::prepend('file.txt', 'Prepended content');

// 删除文件
Storage::delete('file.txt');

// 删除多个文件
Storage::delete(['file1.txt', 'file2.txt']);

2.2 检查文件

1
2
3
4
5
// 文件是否存在
$exists = Storage::exists('file.txt');

// 文件缺失
$missing = Storage::missing('file.txt');

2.3 文件信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 文件大小
$size = Storage::size('file.txt');

// 最后修改时间
$time = Storage::lastModified('file.txt');

// 文件路径
$path = Storage::path('file.txt');

// 文件 URL
$url = Storage::url('file.txt');

// 临时 URL(S3)
$url = Storage::temporaryUrl('file.txt', now()->addMinutes(5));

3. 目录操作

3.1 目录管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 获取目录下所有文件
$files = Storage::files('directory');

// 递归获取所有文件
$files = Storage::allFiles('directory');

// 获取目录下所有目录
$directories = Storage::directories('directory');

// 递归获取所有目录
$directories = Storage::allDirectories('directory');

// 创建目录
Storage::makeDirectory('directory');

// 删除目录
Storage::deleteDirectory('directory');

4. 文件上传

4.1 基本上传

1
2
3
4
5
6
public function upload(Request $request)
{
$path = $request->file('avatar')->store('avatars');

return $path;
}

4.2 指定磁盘

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

4.3 自定义文件名

1
2
3
4
5
$path = $request->file('avatar')->storeAs(
'avatars',
$request->user()->id . '.' . $request->file('avatar')->extension(),
's3'
);

4.4 上传验证

1
2
3
4
5
6
7
8
9
10
public function upload(Request $request)
{
$validated = $request->validate([
'avatar' => 'required|image|max:1024|mimes:jpeg,png,gif',
]);

$path = $request->file('avatar')->store('avatars');

return response()->json(['path' => $path]);
}

5. 文件下载

5.1 下载文件

1
2
3
return Storage::download('file.txt');

return Storage::download('file.txt', 'custom-name.txt');

5.2 响应文件

1
return Storage::response('file.txt');

6. 多磁盘操作

6.1 切换磁盘

1
2
3
4
5
// 使用默认磁盘
Storage::put('file.txt', 'content');

// 使用指定磁盘
Storage::disk('s3')->put('file.txt', 'content');

6.2 跨磁盘复制

1
2
3
4
Storage::disk('local')->writeStream(
'file.txt',
Storage::disk('s3')->readStream('file.txt')
);

7. 实战案例

7.1 文件上传服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

namespace App\Services;

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

class FileUploadService
{
public function upload(UploadedFile $file, string $directory = 'uploads'): string
{
$filename = Str::random(40) . '.' . $file->extension();

return $file->storeAs($directory, $filename, 'public');
}

public function delete(string $path): bool
{
if (Storage::disk('public')->exists($path)) {
return Storage::disk('public')->delete($path);
}

return false;
}

public function url(string $path): string
{
return Storage::disk('public')->url($path);
}
}

7.2 图片处理上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

namespace App\Services;

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

class ImageUploadService
{
public function upload(UploadedFile $file, array $sizes = []): array
{
$paths = [];
$filename = Str::random(40);
$extension = $file->extension();

foreach ($sizes as $name => $dimensions) {
$image = Image::make($file)
->resize($dimensions['width'], $dimensions['height'], function ($constraint) {
$constraint->aspectRatio();
})
->encode($extension, 80);

$path = "images/{$name}/{$filename}.{$extension}";

Storage::disk('public')->put($path, $image);

$paths[$name] = $path;
}

return $paths;
}
}

8. 最佳实践

8.1 安全上传

1
2
3
4
5
6
7
// 验证文件类型
$validated = $request->validate([
'file' => 'required|file|mimes:pdf,doc,docx|max:10240',
]);

// 安全文件名
$filename = Str::random(40) . '.' . $file->extension();

8.2 私有文件

1
2
3
4
5
6
7
8
9
10
11
12
// 使用 local 磁盘存储私有文件
Storage::disk('local')->put('private/file.txt', $content);

// 通过控制器访问
public function download($file)
{
if (!auth()->user()->canAccess($file)) {
abort(403);
}

return Storage::disk('local')->download($file);
}

9. 总结

Laravel 的文件存储系统提供了强大的文件管理能力:

  1. 多磁盘支持:本地、S3、FTP 等
  2. 简单 API:统一的文件操作接口
  3. 安全上传:完善的验证机制
  4. 云服务集成:无缝对接云存储

参考资料