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
Requires
- php: ^8.0
- league/flysystem: ^3.0
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_prefix 与 public_prefix(务必区分)
path_prefix:存储层的路径前缀(key 前缀),用于组织目录、做安全目录限制。
例如uploads,则上传后的路径可能是uploads/20260123/xxxx.jpg。public_prefix(仅 local):访问层的 URL 前缀(不含域名),用于拼接对外访问地址。
例如/storage,则最终 URL 是/storage/{filePath}。
示例(默认配置):
- root_path:
public/storage - path_prefix:
uploads - 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.jpguploads/20250116/9i0j1k2l3m4n5o6p7.pdf
安全特性
- 路径遍历防护:自动清理路径中的
../等危险字符 - 安全目录限制:文件必须存储在配置的
path_prefix目录内 - 文件类型验证:支持白名单和黑名单验证
- 文件大小限制:防止上传过大文件
常见问题
Q: 如何修改文件大小限制?
A: 在配置文件中修改 single_limit 和 total_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: 初始版本,支持基本的上传、删除功能
- 支持多种存储驱动
- 完善的文件验证和安全防护
- 清晰的分层架构