Laravel文件上传核心是Filesystem统一接口,通过配置public磁盘(本地)或s3磁盘(AWS)切换存储,需验证文件、安全命名、生成URL,并支持跨磁盘读写操作。
在 Laravel 中实现文件上传和存储,核心是利用其内置的 Filesystem 统一接口,通过配置驱动(如 local 或 s3)切换存储位置,无需修改业务代码。关键在于正确配置磁盘、验证上传、安全保存并生成可访问路径。
默认情况下,Laravel 已预设 public 磁盘,适合上传头像、文章图片等需公开访问的文件。
config/filesystems.php 中 public 磁盘使用 local 驱动,并指向 storage/app/public 目录php artisan storage:link 创建 public/storage → storage/app/public 的符号链接,让 Web 服务器能直接访问if ($request->hasFile('avatar')) {
$path = $request->file('avatar')->store('avatars', 'public');
// 返回类似:avatars/9a7f2e3d.jpg
$url = Storage::disk('public')->url($path); // /storage/avatars/9a7f2e3d.jpg
}
S3 适合生产环境的大文件、高并发或 CDN 分发场景。需先安装 AWS SDK:composer require aws/aws-sdk-php。
.env 中填写 S3 凭据:
AWS_ACCESS_KEY_ID=your_key AWS_SECRET_ACCESS_KEY=your_secret AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET=your-bucket-name AWS_ENDPOINT=https://s3.your-region.amazonaws.com
config/filesystems.php 添加 S3 磁盘(或直接用预设的 s3):
'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'), // 可选,用于自定义域名或 CDN
],
$path = $request->file('video')->store('videos', 's3');
// 返回类似:videos/abc123.mp4
$url = Storage::disk('s3')->url($path); // 完整 HTTPS URL
不能只依赖前端限制,后端必须校验文件类型、大小和内容合法性。
request()->validate([
'avatar' => 'required|image|mimes:jpg,jpeg,png,gif|max:2048', // 2MB
'document' => 'required|mimes:pdf,doc,docx|max:5120',
]);
$file = $request->file('avatar');
$extension = $file->getClientOriginalExtension();
$filename = Str::uuid() . '.' . $extension; // 更安全的命名
$path = $file->storeAs('avatars', $filename, 'public');
intervention/image 包)无论存在本地还是 S3,调用方式一致,便于后期迁移或灰度切换。
// local 磁盘返回 /storage/xxx
// s3 磁盘返回 https://bucket.s3.region.amazonaws.com/xxx
$url = Storage::disk('public')->url('av
atars/123.jpg');
$url = Storage::disk('s3')->url('videos/demo.mp4');
Storage::disk('s3')->exists('videos/demo.mp4'); // true/false
Storage::disk('public')->delete('avatars/old.jpg');
return Storage::disk('s3')->download('reports/2025.pdf');
基本上就这些。本地开发用 public 磁盘快速验证,上线切到 s3 只需改配置和环境变量,不碰业务逻辑。注意权限控制(如私有 S3 对象)、CDN 缓存策略和大文件超时设置,就能覆盖大多数上传需求。