yuanhao/file-manager

Webman plugin yuanhao/file-manager

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/yuanhao/file-manager

v1.0.1 2026-01-23 07:51 UTC

This package is auto-updated.

Last update: 2026-01-23 08:51:35 UTC


README

简介

这是一个基于 Flysystem 的文件上传服务包,支持多种存储驱动(本地、OSS、S3、COS、七牛云等),提供统一的文件上传、删除等操作接口。

重要说明

  • 这是一个独立的上传服务包,可以不依赖任何框架使用
  • 不包含路由定义,您需要在自己的项目中实现路由和控制器逻辑
  • 配置可以通过数组传入,不强制要求配置文件

功能特性

  • ✅ 支持多种存储驱动(本地、OSS、S3、COS、七牛云)
  • ✅ 文件上传验证(大小、类型、数量限制)
  • ✅ 路径安全验证(防止路径遍历攻击)
  • ✅ 支持多种上传方式(HTTP 上传、字符串上传、服务端文件上传)
  • ✅ 自动生成文件路径(按日期分类)
  • ✅ 清晰的代码架构(Controller → Service → Validator/Helper)

快速开始

独立使用(不依赖框架)

<?php
require 'vendor/autoload.php';

use Yuanhao\FileManager\Controller\FileController;

// 配置数组
$config = [
    'default_driver' => 'local',
    'single_limit' => 10 * 1024 * 1024,  // 10MB
    'include' => ['jpg', 'png', 'pdf'],
    'exclude' => ['php', 'exe'],
    // 存储路径前缀(文件最终 key 形如:{path_prefix}/YYYYMMDD/{filename})
    'path_prefix' => 'uploads',
    'drivers' => [
        'local' => [
            'driver' => 'local',
            // 磁盘根目录(真实存储位置)
            'root_path' => __DIR__ . '/storage',
            // URL 访问前缀(不含域名)
            // 例如你把 __DIR__/storage 暴露为 http://host/storage,则这里配置为 /storage
            'public_prefix' => '/storage',
        ],
    ],
];

// 创建控制器
$controller = new FileController($config);

// 方式1:通用上传方法(接受临时文件路径,不依赖任何框架)
// PHP 上传文件时会自动保存到临时目录,直接使用 $_FILES['file']['tmp_name'] 即可
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
    // 直接使用 PHP 自动生成的临时文件路径,无需手动保存
    $result = $controller->uploadNotWebman($_FILES['file']['tmp_name'], $_FILES['file']['name']);
    print_r($result);
    // 注意:PHP 会在脚本执行结束后自动清理临时文件,无需手动删除
}

// 方式2:上传字符串内容
$result = $controller->uploadString('Hello World', 'test.txt');
print_r($result);

// 方式3:从服务端文件路径上传
$result = $controller->uploadFromServer('/path/to/file.jpg');
print_r($result);

// 删除文件
$result = $controller->delete('uploads/20250116/file.jpg');
print_r($result);

配置说明

1. 配置方式

方式一:使用配置文件(Webman 框架)

配置文件位置:config/plugin/yuanhao/file-manager/app.php

方式二:直接传入配置数组(不依赖框架)

可以在创建 FileController 时直接传入配置数组,无需配置文件。

2. 关于 path_prefixpublic_prefix(务必区分)

  • path_prefix:存储层的路径前缀(key 前缀),用于组织目录、做安全目录限制。
    例如 uploads,则上传后的路径可能是 uploads/20260123/xxxx.jpg
  • public_prefix(仅 local):访问层的 URL 前缀(不含域名),用于拼接对外访问地址。
    例如 /storage,则最终 URL 是 /storage/{filePath}

示例(默认配置):

  • root_pathpublic/storage
  • path_prefixuploads
  • public_prefix/storage
  • 最终 URL:/storage/uploads/20260123/xxxx.jpg

3. 配置结构

return [
    // 默认存储驱动
    'default_driver' => env('FILE_MANAGER_DRIVER', 'local'),

    // 文件上传验证配置
    'single_limit' => env('FILE_MANAGER_SINGLE_LIMIT', 10 * 1024 * 1024),  // 单个文件大小限制(默认 10MB)
    'total_limit' => env('FILE_MANAGER_TOTAL_LIMIT', 50 * 1024 * 1024),      // 总大小限制(默认 50MB)
    'nums' => env('FILE_MANAGER_NUMS', 10),                                  // 文件数量限制(默认 10 个)
    
    // 文件类型白名单(空数组表示不限制)
    'include' => ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', ...],
    
    // 文件类型黑名单(禁止上传的类型)
    'exclude' => ['php', 'php3', 'exe', 'bat', 'sh', ...],

    // 路径前缀(安全目录)
    'path_prefix' => env('FILE_MANAGER_PATH_PREFIX', 'uploads'),

    // 存储驱动配置
    'drivers' => [
        // 本地存储
        'local' => [
            'driver' => 'local',
            'root_path' => public_path('storage'),
            // local 对外 URL 前缀(不含域名)
            'public_prefix' => '/storage',
        ],
        
        // 阿里云 OSS
        'oss' => [
            'driver' => 'oss',
            'access_key_id' => 'your-access-key-id',
            'access_key_secret' => 'your-access-key-secret',
            'bucket' => 'your-bucket',
            'endpoint' => 'oss-cn-hangzhou.aliyuncs.com',
        ],
        
        // 腾讯云 COS
        'cos' => [
            'driver' => 'cos',
            'app_id' => 'your-app-id',
            'secret_id' => 'your-secret-id',
            'secret_key' => 'your-secret-key',
            'region' => 'ap-beijing',
            'bucket' => 'your-bucket',
        ],
        
        // 更多驱动配置...
    ],
];

API 使用说明

注意:这是一个文件上传服务包,不包含路由定义。您需要在自己的项目中实现路由和控制器逻辑。

可用方法列表

方法 说明 依赖框架 适用场景
upload() Webman HTTP 上传 需要 Webman Webman 框架项目
uploadNotWebman() 通用上传(临时文件路径) 任何框架或独立项目,可直接使用 PHP 的 $_FILES['file']['tmp_name']
uploadString() 上传字符串内容 Base64、Data URI 等
uploadFromServer() 服务端文件上传 服务器本地文件上传到存储
delete() 删除文件 删除已上传的文件

方式一:通过 Controller(推荐,支持框架和独立使用)

1.1 使用配置文件(Webman 框架)

use Yuanhao\FileManager\Controller\FileController;

// 自动读取配置文件 config('plugin.yuanhao.file-manager.app')
$controller = new FileController();

1.2 直接传入配置(不依赖框架)

use Yuanhao\FileManager\Controller\FileController;

// 直接传入配置数组,不依赖框架和配置文件
$config = [
    'default_driver' => 'local',
    'single_limit' => 10 * 1024 * 1024,
    'total_limit' => 50 * 1024 * 1024,
    'nums' => 10,
    'include' => ['jpg', 'jpeg', 'png', 'gif', 'pdf'],
    'exclude' => ['php', 'exe', 'bat', 'sh'],
    'path_prefix' => 'uploads',
    'drivers' => [
        'local' => [
            'driver' => 'local',
            'root_path' => '/path/to/storage',
            'public_prefix' => '/storage',
        ],
    ],
];

$controller = new FileController($config);

1.3 使用示例

use Yuanhao\FileManager\Controller\FileController;

// 创建控制器实例(使用配置文件或传入配置数组)
$controller = new FileController();

// 1. Webman HTTP 上传(需要 Webman 框架)
$file = request()->file('file');
$result = $controller->upload($file);

// 2. 通用上传方法(不依赖 Webman,接受临时文件路径)
// 适用于任何框架或独立 PHP 项目
// 示例1:直接使用 PHP 的临时文件路径(推荐)
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
    // PHP 上传文件时会自动保存到临时目录,tmp_name 就是临时文件路径
    // 直接使用即可,无需手动保存或移动文件
    $result = $controller->uploadNotWebman($_FILES['file']['tmp_name'], $_FILES['file']['name']);
}

// 示例2:如果已经验证过文件,可以跳过重复验证以提高性能
$result = $controller->uploadNotWebman($_FILES['file']['tmp_name'], $_FILES['file']['name'], false);

// 示例3:使用其他来源的临时文件路径(如已保存的文件)
$result = $controller->uploadNotWebman('/tmp/custom_file.pdf', 'document.pdf');

// 3. 上传字符串内容(不依赖框架)
$result = $controller->uploadString(
    'data:image/png;base64,iVBORw0KGgoAAAANS...',
    'image.png'  // 可选文件名
);

// 4. 从服务端文件路径上传(不依赖框架)
$result = $controller->uploadFromServer(
    '/var/www/temp/image.jpg',
    'custom-name.jpg'  // 可选目标文件名
);

// 5. 删除文件(不依赖框架)
$result = $controller->delete('uploads/20250116/abc123.jpg');

方式二:直接使用 Service(最灵活,完全不依赖框架)

use Yuanhao\FileManager\FileManagerFactory;
use Yuanhao\FileManager\Service\FileUploadService;
use Yuanhao\FileManager\Service\FileValidator;
use Yuanhao\FileManager\Service\PathHelper;

// 配置(可以是数组,不依赖配置文件)
$driverConfig = [
    'driver' => 'local',
    'root_path' => '/path/to/storage',
    'public_prefix' => '/storage',
];

// 初始化组件
$fileManager = FileManagerFactory::create($driverConfig);
$validator = new FileValidator([
    'single_limit' => 10 * 1024 * 1024,
    'total_limit' => 50 * 1024 * 1024,
    'nums' => 10,
    'include' => ['jpg', 'png', 'pdf'],
    'exclude' => ['php', 'exe'],
]);
$pathHelper = new PathHelper('uploads');

// 创建服务
$service = new FileUploadService($fileManager, $validator, $pathHelper);

// 使用服务(完全不依赖框架)
$result = $service->uploadFromPath('/tmp/file.jpg', 'original.jpg');
$result = $service->uploadString('file contents', 'file.txt');
$result = $service->uploadFromServer('/var/www/file.jpg');
$result = $service->delete('uploads/20250116/file.jpg');

方式三:在自己的控制器中使用(框架集成)

// 在您的控制器中
namespace App\Controller;

use Yuanhao\FileManager\Controller\FileController;

class YourController
{
    protected FileController $fileController;
    
    public function __construct()
    {
        $this->fileController = new FileController();
    }
    
    // 实现您的路由处理方法
    public function upload()
    {
        $file = request()->file('file');
        return json($this->fileController->upload($file));
    }
    
    // 通用上传方法(不依赖 Webman)
    // 适用于非 Webman 框架,直接使用 PHP 的临时文件路径
    public function uploadFile()
    {
        // 1. 接收上传的文件
        $uploadedFile = $_FILES['file'] ?? null;
        if (!$uploadedFile || $uploadedFile['error'] !== UPLOAD_ERR_OK) {
            return json(['code' => -1, 'message' => '文件上传失败']);
        }
        
        // 2. 直接使用 PHP 自动生成的临时文件路径
        // PHP 上传文件时会自动保存到临时目录,tmp_name 就是临时文件路径
        $tmpPath = $uploadedFile['tmp_name'];
        $originalName = $uploadedFile['name'];
        
        // 3. 使用临时文件路径上传(文件会在上传后被自动清理)
        $result = $this->fileController->uploadNotWebman($tmpPath, $originalName);
        
        return json($result);
    }
    
    public function uploadString()
    {
        $contents = request()->post('contents');
        $filename = request()->post('filename');
        return json($this->fileController->uploadString($contents, $filename));
    }
    
    public function delete($filePath)
    {
        return json($this->fileController->delete($filePath));
    }
}

然后在路由文件中定义:

// config/route.php 或您的路由文件
use App\Controller\YourController;

Route::post('/upload', [YourController::class, 'upload']);  // Webman 上传(需要 Webman 框架)
Route::post('/upload-file', [YourController::class, 'uploadFile']);  // 通用上传(不依赖 Webman,直接使用 $_FILES['tmp_name'])
Route::post('/upload-string', [YourController::class, 'uploadString']);
Route::delete('/delete/{filePath:.+}', [YourController::class, 'delete']);

返回格式说明

所有接口统一返回格式:

[
    'code' => 0,        // 0 表示成功,-1 表示失败
    'message' => '',    // 提示信息
    'data' => [        // 成功时返回的数据(可选)
        'url' => '',   // 文件访问 URL
        'path' => '',  // 文件存储路径
        'name' => '',  // 文件名
        'size' => 0,   // 文件大小(字节)
        'type' => '',  // MIME 类型
    ]
]

路径生成规则

文件存储路径格式:{path_prefix}/YYYYMMDD/{随机文件名}.{扩展名}

示例:

  • uploads/20250116/a1b2c3d4e5f6g7h8.jpg
  • uploads/20250116/9i0j1k2l3m4n5o6p7.pdf

安全特性

  1. 路径遍历防护:自动清理路径中的 ../ 等危险字符
  2. 安全目录限制:文件必须存储在配置的 path_prefix 目录内
  3. 文件类型验证:支持白名单和黑名单验证
  4. 文件大小限制:防止上传过大文件

常见问题

Q: 如何修改文件大小限制?

A: 在配置文件中修改 single_limittotal_limit 参数。

Q: 如何添加允许的文件类型?

A: 在配置文件的 include 数组中添加扩展名(不含点号)。

Q: 如何禁用文件类型限制?

A: 将 include 设置为空数组 []

Q: 文件路径前缀可以设置为空吗?

A: 可以,设置为空字符串 '' 则不使用前缀,文件直接存储在根目录。

Q: 如何切换存储驱动?

A: 修改配置文件中的 default_driver 参数,或通过环境变量 FILE_MANAGER_DRIVER 设置。

架构说明

FileController (控制器层)
    ↓ 调用
FileUploadService (服务层)
    ↓ 使用
FileValidator (验证层) + PathHelper (路径处理层)
  • Controller:只负责接收请求,调用服务层
  • Service:处理业务逻辑
  • Validator:文件验证(大小、类型)
  • PathHelper:路径处理(生成、清理、验证)

更新日志

  • v1.0.0: 初始版本,支持基本的上传、删除功能
  • 支持多种存储驱动
  • 完善的文件验证和安全防护
  • 清晰的分层架构