david-dong/unified-upload

多云存储上传组件,支持本地、腾讯云COS、阿里云OSS、七牛云

Maintainers

Package info

github.com/DavidDongs/unified-upload

pkg:composer/david-dong/unified-upload

Statistics

Installs: 8

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.2 2026-04-10 15:42 UTC

This package is auto-updated.

Last update: 2026-04-10 15:45:32 UTC


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.phpconfig/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