Laravel 文件上传与 Storage 抽象:从本地磁盘平滑切到阿里云 OSS
test12026-10-026 次阅读
别把存储写死在业务里
文件上传最怕的是业务代码里直接拼本地路径。一旦要上对象存储,得改无数处。Laravel 的 Storage 门面把所有磁盘统一成一套 put/get/url 接口,本地、S3、阿里云 OSS 只是换一个 disk 配置,业务层一行不用动。
第一步:用 FormRequest 收口校验
文件类型、大小、是否必填都交给 FormRequest,控制器保持干净。
// app/Http/Requests/UploadAvatarRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UploadAvatarRequest extends FormRequest
{
public function authorize(): bool
{
return (bool) $this->user();
}
public function rules(): array
{
return [
'avatar' => [
'required',
'image',
'mimes:jpeg,png,webp',
'max:2048', // 2MB
],
];
}
}
第二步:控制器只调 Storage
用 store() 生成带随机前缀的路径,返回存储后的访问 URL。后续切 OSS 时这个方法签名完全不变。
// app/Http/Controllers/AvatarController.php
namespace App\Http\Controllers;
use App\Http\Requests\UploadAvatarRequest;
use Illuminate\Support\Facades\Storage;
class AvatarController extends Controller
{
public function store(UploadAvatarRequest $request)
{
$path = $request->file('avatar')->store('avatars', 'public');
return response()->json([
'code' => 0,
'data' => [
'path' => $path,
'url' => Storage::disk('public')->url($path),
],
]);
}
}
第三步:把 public 磁盘接到阿里云 OSS
装好 aliyuncs/oss-sdk-php 后,在 config/filesystems.php 加一个 oss 磁盘。把默认改成 oss,或上传时显式传 'oss' 即可切换,业务零改动。
// config/filesystems.php
'disks' => [
'oss' => [
'driver' => 'oss',
'access_key' => env('OSS_ACCESS_KEY'),
'secret' => env('OSS_SECRET'),
'endpoint' => env('OSS_ENDPOINT'),
'bucket' => env('OSS_BUCKET'),
'prefix' => 'uploads',
],
],
// 切换默认磁盘
'default' => env('FILESYSTEM_DISK', 'oss'),
// .env
FILESYSTEM_DISK=oss
OSS_ACCESS_KEY=your-key
OSS_SECRET=your-secret
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
OSS_BUCKET=my-bucket
工程要点
- 永远通过
Storage::url()取访问地址,不要手拼域名,否则换存储时全要改。 - 用户上传内容要做 MIME 与扩展名双重校验,避免上传可执行文件造成安全隐患。
- 大文件用
storeUploadedFile配合分片或前端直传 OSS(签发临时凭证),别让应用服务器经手整份大文件。 - 本地 disk 的
url()依赖php artisan storage:link软链,上云后这步可以省掉。 - 多环境用不同 bucket 或 prefix,避免测试数据污染生产。
T
test1
文章作者
别把存储写死在业务里 文件上传最怕的是业务代码里直接拼本地路径。一旦要上对象存储,得改无数处。Laravel 的 St...
- 分类
- 技术
- 发布时间
- 2026-10-02
- 字数
- 约 2240 字
- 阅读
- 6 次
