Laravel可通过配置多磁盘(local_dev、s3_videos、oss_images)、安装overtrue/flysystem-oss、动态调用Storage::disk()按MIME类型路由上传,并结合url()/temporaryUrl()及异常捕获实现生产级多云文件存储。

你想让Laravel项目里的文件上传不再卡在本地磁盘,能自动存到S3、阿里云OSS或百度网盘,还能按文件类型分流、权限可控、出错有日志——这不是设想,是今天就能搭出来的生产级能力。
配置基础文件系统与多磁盘策略
打开 config/filesystems.php,找到 'disks' 数组,在末尾添加三个专用磁盘配置:
本地开发用的 local_dev 磁盘,根目录设为 storage_path('app/dev'),visibility 设为 'private',避免开发时误曝敏感测试文件;
S3 视频专用磁盘 s3_videos,driver 为 's3',region 必须填你创建 Bucket 时选的实际区域(如 cn-north-1),【bucket 值只写桶名,不带域名后缀】;
OSS 图片磁盘 oss_images,driver 设为 'oss',endpoint 必须带 https:// 协议头(例如 https://oss-cn-shanghai.aliyuncs.com),【漏掉 https:// 会导致 cURL error 60 或 7】。
对接阿里云 OSS:装对包、配准字段、清缓存
执行命令安装 Flysystem OSS 适配器:
composer require overtrue/flysystem-oss:^4.0
注意:只装 aliyuncs/oss-sdk-php 不够,它只是底层 SDK,没有注册 Laravel 的 disk 驱动;
编辑 .env,填入四组必填项:
OSS_ACCESS_KEY_ID=从 RAM 子账号获取的密钥(不用主账号)
OSS_ACCESS_KEY_SECRET=对应密钥
OSS_ENDPOINT=https://oss-cn-shanghai.aliyuncs.com
OSS_BUCKET=your-image-bucket-name
改完立刻运行:php artisan config:clear,否则新配置不会生效,Storage::disk('oss_images') 会直接抛出 Disk [oss_images] does not exist。
上传文件并按类型自动路由到不同磁盘
第一步:在控制器中获取上传文件对象
$file = $request->file('attachment');
第二步:根据 MIME 类型判断归属
如果是 image/*,走 oss_images 磁盘;视频类 video/mp4 或 video/quicktime 走 s3_videos;其余走 local_dev。
第三步:调用对应磁盘写入
Storage::disk($disk)->put("uploads/{$uuid}/{$file->getClientOriginalName()}", file_get_contents($file));
这一步不能用 $file->store(),因为它默认走 FILESYSTEM_DISK,无法动态切换;必须显式指定 disk() 才能实现路由逻辑。
生成可访问链接与处理私有资源
公开资源直接用 url():
Storage::disk('oss_images')->url('uploads/abc123/photo.jpg') → 返回带签名的 HTTPS 地址。
私有资源(如用户合同 PDF)必须用 temporaryUrl():
Storage::disk('s3_videos')->temporaryUrl('secure/2026/contract.pdf', now()->addMinutes(30)) → 30 分钟后链接失效。
注意:S3 和 OSS 的 temporaryUrl 实现机制不同,OSS 需要额外配置 isCName 和 access_key_secret 到适配器参数中,否则返回空字符串。
错误捕获与日志定位关键问题
方法一:用 try-catch 包裹 put 操作,捕获 UnableToWriteFile 异常
方法二:检查 storage/logs/laravel.log,搜索关键词 OSSException 或 Aws\S3\Exception\S3Exception
方法三:对大文件(>50MB)禁用 put(),改用 putFileAs() + 分片中间件,否则内存溢出或超时中断不会抛异常,只会静默返回 false。


















