david-dong / unified-upload
多云存储上传组件,支持本地、腾讯云COS、阿里云OSS、七牛云
v1.0.2
2026-04-10 15:42 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 | Trait |
| Laravel | 9.x / 10.x / 11.x | ServiceProvider + Trait |
| Hyperf | 3.x | Config + Trait |
安装
composer require david-dong/unified-upload
快速开始
ThinkPHP 8 集成
1. 使用配置文件
手动复制 vendor/david-dong/unified-upload/src/config/upload.php 到 config/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/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\admin\controller; use app\BaseController; use DavidDong\UnifiedUpload\ThinkPHP\UploadController; class FileController extends BaseController { use UploadController; // 上传图片 public function uploadImage() { // 数据库或者环境变量获取配置;使用配置文件,则数据为空数组即可 $config = [ 'upload_storage_type' => 'local', 'upload_local_domain' => 'http://localhost:8080/uploads', 'upload_local_root_path' => '/var/www/html/uploads', 'upload_tencent_cos_secret_id' => 'your_secret_id', 'upload_tencent_cos_secret_key' => 'your_secret_key', 'upload_tencent_cos_region' => 'ap-beijing', 'upload_tencent_cos_bucket' => 'your_bucket', 'upload_tencent_cos_cdn_domain' => 'your_cdn_domain', 'upload_aliyun_oss_access_key_id' => 'your_access_key_id', 'upload_aliyun_oss_access_key_secret' => 'your_access_key_secret', 'upload_aliyun_oss_endpoint' => 'oss-cn-hangzhou.aliyuncs.com', 'upload_aliyun_oss_bucket' => 'your_bucket', 'upload_aliyun_oss_cdn_domain' => 'your_cdn_domain', 'upload_qiniu_access_key' => 'your_access_key', 'upload_qiniu_secret_key' => 'your_secret_key', 'upload_qiniu_bucket' => 'your_bucket', 'upload_qiniu_domain' => 'your_domain', 'upload_qiniu_zone' => 'your_zone', 'upload_qiniu_cdn_domain' => 'your_cdn_domain', 'upload_max_file_size' => 1024 * 1024 * 10, 'upload_allow_extensions' => 'jpg,jpeg,png,gif', ]; return $this->uploadImageResponse($config); } }
直接使用 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