thinkphp 通过 flysystem 统一管理多磁盘(本地/七牛/阿里云),上传流程为接收→验证→存指定磁盘,需配置 disks、用 filesystem->disk()->put() 存储、url() 获取适配 url,并加强 mime 校验与目录安全。

ThinkPHP 提供了灵活的文件上传与磁盘存储机制,核心在于统一使用 Filesystem(基于 Flysystem)管理本地、云存储等各类磁盘,上传流程可解耦为「接收文件 → 验证 → 存储到指定磁盘」三步。关键不是写死路径,而是通过配置驱动磁盘行为。
配置多磁盘支持(本地+七牛/阿里云/OSS)
在 config/filesystem.php 中定义多个磁盘,例如:
-
local:默认指向
runtime/upload或自定义本地路径,适合开发测试 -
qiniu:需安装
overtrue/flysystem-qiniu,配置accessKey/secretKey/bucket/domain -
aliyun:使用
alibabacloud/oss-sdk-php+league/flysystem-aws-s3-v3适配器(或官方 OSS Flysystem 适配器)
每个磁盘都可独立设置 root、visibility、url 前缀等,上传时只需指定磁盘名,无需修改业务代码。
上传并存入指定磁盘(带验证与重命名)
控制器中用 think\File 接收,再用 think\Filesystem 写入磁盘:
- 调用
$request->file('image')获取上传文件对象 - 用
validate(['size'=>1024*1024,'ext'=>'jpg,png,gif'])检查大小和扩展名 - 生成唯一文件名:
md5(uniqid().time()).'.'.$file->getExtension() - 写入磁盘:
app('filesystem')->disk('qiniu')->put($saveName, file_get_contents($file->getRealPath()))
注意:不要直接用 $file->move(),它只支持本地移动;跨磁盘存储必须走 Flysystem 的 put 或 writeStream。
获取可访问 URL(自动适配不同磁盘)
不同磁盘返回 URL 方式不同,应封装统一方法:
- 本地磁盘:拼接
config('filesystems.disks.local.url') . '/' . $path - 七牛/阿里云:直接返回
config('filesystems.disks.qiniu.url') . '/' . $path(已含域名) - 推荐做法:在磁盘配置中统一设
'url' => env('QINIU_URL', 'https://xxx.com'),业务层调用app('filesystem')->disk('qiniu')->url($path)
Flysystem 会根据磁盘驱动自动选择 URL 生成逻辑,避免硬编码。
安全与扩展建议
生产环境需额外加固:
- 上传目录禁止执行 PHP(Nginx/Apache 配置限制
.php解析) - 校验文件 MIME 类型(
$file->getMimeType()),不只依赖后缀 - 大文件分片上传?用
resumable.js前端 + 后端合并逻辑,ThinkPHP 可监听临时分片目录并按序合并 - 缩略图处理?上传成功后用
intervention/image加载远程 URL 或本地流,再写入另一磁盘(如thumb)
不复杂但容易忽略细节,比如磁盘配置未生效、URL 拼接漏协议、MIME 校验绕过等。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











