david-dong / unified-upload
多云存储上传组件,支持本地、腾讯云COS、阿里云OSS、七牛云
v1.0.0
2026-04-09 01:44 UTC
Requires
- php: >=8.0
- aliyuncs/oss-sdk-php: ^2.6
- qcloud/cos-sdk-v5: ^2.5
- qiniu/php-sdk: ^7.4
Requires (Dev)
- phpunit/phpunit: ^9.5
README
多云存储上传组件,支持本地、腾讯云 COS、阿里云 OSS、七牛云。
功能特性
- 支持四种存储方式:本地、腾讯云 COS、阿里云 OSS、七牛云
- 统一的接口设计,便于扩展新的存储后端
- 支持文件上传、Base64 上传、文件删除
- 内置文件类型和大小验证
- 运行时动态切换存储方式
- 完善的错误处理和异常机制
- 详细的代码注释,方便理解
- 适配 ThinkPHP、Laravel、Hyperf 三大框架
支持的框架
| 框架 | 版本 | 集成方式 |
|---|---|---|
| ThinkPHP | 8.x | ServiceProvider + Trait |
| Laravel | 9.x / 10.x / 11.x | ServiceProvider + Trait |
| Hyperf | 3.x | Config + Trait |
安装
composer require david-dong/unified-upload
快速开始
ThinkPHP 8 集成
1. 注册服务提供者
在 config/provider.php 中添加:
<?php return [ // ... 其他服务提供者 DavidDong\UnifiedUpload\ThinkPHP\UploadService::class, ];
2. 发布配置文件
php think vendor:publish --name=unified-upload
或手动复制 vendor/david-dong/unified-upload/src/config/upload.php 到 config/upload.php
3. 配置环境变量
在 .env 文件中添加:
# 默认存储类型:local, tencent_cos, aliyun_oss, qiniu UPLOAD_DEFAULT_STORAGE=local # 本地存储 UPLOAD_LOCAL_DOMAIN=http://localhost:8080/uploads UPLOAD_LOCAL_ROOT_PATH=/var/www/uploads # 腾讯云 COS TENCENT_COS_SECRET_ID=your_secret_id TENCENT_COS_SECRET_KEY=your_secret_key TENCENT_COS_REGION=ap-beijing TENCENT_COS_BUCKET=your_bucket # 阿里云 OSS ALIYUN_OSS_ACCESS_KEY_ID=your_access_key_id ALIYUN_OSS_ACCESS_KEY_SECRET=your_access_key_secret ALIYUN_OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com ALIYUN_OSS_BUCKET=your_bucket # 七牛云 QINIU_ACCESS_KEY=your_access_key QINIU_SECRET_KEY=your_secret_key QINIU_BUCKET=your_bucket QINIU_DOMAIN=your_domain
4. 使用示例
<?php namespace app\admin\controller; use app\BaseController; use DavidDong\UnifiedUpload\ThinkPHP\UploadController; class FileController extends BaseController { use UploadController; // 上传图片 public function uploadImage() { return $this->uploadImageResponse(); } // 上传视频 public function uploadVideo() { return $this->uploadVideoResponse(); } // 通用文件上传 public function uploadFile() { return $this->uploadFileResponse(); } }
Laravel 集成
1. 注册服务提供者
在 config/app.php 的 providers 数组中添加:
<?php return [ // ... 其他 providers DavidDong\UnifiedUpload\Laravel\UploadServiceProvider::class, ];
2. 发布配置文件
php artisan vendor:publish --tag=unified-upload
或手动复制 vendor/david-dong/unified-upload/src/config/upload.php 到 config/upload.php
3. 配置环境变量
在 .env 文件中添加:
# 默认存储类型:local, tencent_cos, aliyun_oss, qiniu UPLOAD_DEFAULT_STORAGE=local # 本地存储 UPLOAD_LOCAL_DOMAIN=http://localhost:8080/uploads UPLOAD_LOCAL_ROOT_PATH=/var/www/html/uploads # 腾讯云 COS TENCENT_COS_SECRET_ID=your_secret_id TENCENT_COS_SECRET_KEY=your_secret_key TENCENT_COS_REGION=ap-beijing TENCENT_COS_BUCKET=your_bucket # 阿里云 OSS ALIYUN_OSS_ACCESS_KEY_ID=your_access_key_id ALIYUN_OSS_ACCESS_KEY_SECRET=your_access_key_secret ALIYUN_OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com ALIYUN_OSS_BUCKET=your_bucket # 七牛云 QINIU_ACCESS_KEY=your_access_key QINIU_SECRET_KEY=your_secret_key QINIU_BUCKET=your_bucket QINIU_DOMAIN=your_domain
4. 使用示例
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use DavidDong\UnifiedUpload\Laravel\UploadController; class FileController extends Controller { use UploadController; // 上传图片 public function uploadImage() { return $this->uploadImageResponse(); } // 上传视频 public function uploadVideo() { return $this->uploadVideoResponse(); } // 通用文件上传 public function uploadFile() { return $this->uploadFileResponse(); } }
Hyperf 3 集成
1. 复制配置文件
将 vendor/david-dong/unified-upload/src/config/upload.php 复制到 config/autoload/upload.php
2. 配置环境变量
在 .env 文件中添加:
# 默认存储类型:local, tencent_cos, aliyun_oss, qiniu UPLOAD_DEFAULT_STORAGE=local # 本地存储 UPLOAD_LOCAL_DOMAIN=http://localhost:8080/uploads UPLOAD_LOCAL_ROOT_PATH=/var/www/html/uploads # 腾讯云 COS TENCENT_COS_SECRET_ID=your_secret_id TENCENT_COS_SECRET_KEY=your_secret_key TENCENT_COS_REGION=ap-beijing TENCENT_COS_BUCKET=your_bucket # 阿里云 OSS ALIYUN_OSS_ACCESS_KEY_ID=your_access_key_id ALIYUN_OSS_ACCESS_KEY_SECRET=your_access_key_secret ALIYUN_OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com ALIYUN_OSS_BUCKET=your_bucket # 七牛云 QINIU_ACCESS_KEY=your_access_key QINIU_SECRET_KEY=your_secret_key QINIU_BUCKET=your_bucket QINIU_DOMAIN=your_domain
3. 使用示例
<?php namespace App\Http\Controller; use Hyperf\HttpServer\Contract\RequestInterface; use DavidDong\UnifiedUpload\Hyperf\UploadController; class FileController extends AbstractController { use UploadController; // 上传图片 public function uploadImage(RequestInterface $request) { return $this->uploadImageResponse($request); } // 上传视频 public function uploadVideo(RequestInterface $request) { return $this->uploadVideoResponse($request); } // 通用文件上传 public function uploadFile(RequestInterface $request) { return $this->uploadFileResponse($request); } }
直接使用 UploadManager
如果不想使用框架集成,也可以直接使用 UploadManager:
<?php use DavidDong\UnifiedUpload\UploadManager; // 配置 $config = [ 'default' => 'aliyun_oss', 'storages' => [ 'local' => [ 'domain' => 'http://localhost:8080/uploads', 'root_path' => '/var/www/uploads', ], 'aliyun_oss' => [ 'access_key_id' => 'your_access_key_id', 'access_key_secret' => 'your_access_key_secret', 'endpoint' => 'oss-cn-hangzhou.aliyuncs.com', 'bucket' => 'your_bucket', ], ], ]; // 创建管理器 $manager = new UploadManager($config); // 上传图片 $result = $manager->uploadImage('/path/to/image.jpg'); // 上传文件 $result = $manager->upload('/path/to/file.pdf', 'documents/'); // 切换存储 $manager->setStorage('tencent_cos'); $result = $manager->upload('/path/to/video.mp4', 'videos/'); // 删除文件 $manager->delete('images/2024/01/abc123.jpg'); // 获取文件 URL $url = $manager->getUrl('images/2024/01/abc123.jpg');
API 文档
UploadManager 核心方法
| 方法 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| upload($filePath, $objectKey) | 上传文件 | filePath: 本地文件路径, objectKey: 存储路径 | ['url' => '', 'path' => ''] |
| uploadBase64($base64Data, $objectKey) | 上传 Base64 数据 | base64Data: Base64字符串, objectKey: 存储路径 | 同上 |
| uploadImage($filePath, $prefix) | 上传图片 | filePath: 文件路径, prefix: 路径前缀 | 同上 |
| uploadVideo($filePath, $prefix) | 上传视频 | filePath: 文件路径, prefix: 路径前缀 | 同上 |
| uploadAudio($filePath, $prefix) | 上传音频 | filePath: 文件路径, prefix: 路径前缀 | 同上 |
| uploadDocument($filePath, $prefix) | 上传文档 | filePath: 文件路径, prefix: 路径前缀 | 同上 |
| delete($objectKey) | 删除文件 | objectKey: 存储路径 | bool |
| getUrl($objectKey) | 获取文件 URL | objectKey: 存储路径 | string |
| exists($objectKey) | 检查文件是否存在 | objectKey: 存储路径 | bool |
| setStorage($type) | 切换存储类型 | type: 存储类型标识 | $this |
| getCurrentStorage() | 获取当前存储类型 | - | string |
| generateObjectKey($filename, $prefix) | 生成存储路径 | filename: 原文件名, prefix: 路径前缀 | string |
存储类型
| 类型 | 标识 | 说明 |
|---|---|---|
| 本地存储 | local | 存储在服务器本地文件系统 |
| 腾讯云 COS | tencent_cos | 腾讯云对象存储 |
| 阿里云 OSS | aliyun_oss | 阿里云对象存储 |
| 七牛云 | qiniu | 七牛云对象存储 |
扩展新的存储后端
实现 UploaderInterface 接口即可:
<?php namespace App\Upload; use DavidDong\UnifiedUpload\Contract\AbstractUploader; use DavidDong\UnifiedUpload\Exception\UploadException; class CustomUploader extends AbstractUploader { public const STORAGE_TYPE = 'custom'; public function upload(string $filePath, string $objectKey): array { // 验证文件 $this->validateFile($filePath, $objectKey); // 标准化对象键 $objectKey = $this->normalizeObjectKey($objectKey); // TODO: 实现上传逻辑 // ... return [ 'url' => $this->buildUrl($objectKey), 'path' => $objectKey, ]; } public function uploadBase64(string $base64Data, string $objectKey): array { // TODO: 实现 Base64 上传逻辑 } public function delete(string $objectKey): bool { // TODO: 实现删除逻辑 } public function getUrl(string $objectKey): string { return $this->buildUrl($this->normalizeObjectKey($objectKey)); } public function exists(string $objectKey): bool { // TODO: 实现检查逻辑 } public function getStorageType(): string { return self::STORAGE_TYPE; } }
然后在配置中添加新的存储类型即可。
目录结构
david-dong/unified-upload/
├── composer.json
├── README.md
├── .gitignore
└── src/
├── UploadManager.php
├── Contract/
│ ├── UploaderInterface.php
│ └── AbstractUploader.php
├── Adapter/
│ ├── LocalUploader.php
│ ├── TencentCosUploader.php
│ ├── AlibabaOssUploader.php
│ └── QiniuUploader.php
├── Exception/
│ └── UploadException.php
├── ThinkPHP/
│ ├── UploadService.php
│ └── UploadController.php
├── Laravel/
│ ├── UploadServiceProvider.php
│ └── UploadController.php
├── Hyperf/
│ ├── UploadConfig.php
│ └── UploadController.php
└── config/
└── upload.php
License
MIT