文件系统
最后更新: 2026-01-27 11:02:47文件系统
Unicode Framework 提供了统一的文件系统接口,支持本地存储和多种云存储服务。
文件系统基础
获取文件系统实例
use Unicode\Framework\Filesystem\FilesystemManager;
use Unicode\Framework\Config\Config;
$config = Config::getInstance();
$filesystem = new FilesystemManager($config);
// 获取默认磁盘
$disk = $filesystem->disk();
// 获取指定磁盘
$disk = $filesystem->disk('s3');
$disk = $filesystem->disk('oss');
本地存储
基本使用
$disk = $filesystem->disk('local');
// 写入文件
$disk->put('file.txt', 'content');
// 读取文件
$content = $disk->get('file.txt');
// 检查文件是否存在
if ($disk->exists('file.txt')) {
$content = $disk->get('file.txt');
}
// 删除文件
$disk->delete('file.txt');
配置
// config/filesystem.php
return [
'default' => 'local',
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'url' => '/storage',
],
],
];
云存储
AWS S3
// 配置
return [
'disks' => [
's3' => [
'driver' => 's3',
'bucket' => 'my-bucket',
'region' => 'us-east-1',
'key' => 'your-access-key',
'secret' => 'your-secret-key',
],
],
];
// 使用
$disk = $filesystem->disk('s3');
$disk->put('file.txt', 'content');
阿里云 OSS
// 配置
return [
'disks' => [
'oss' => [
'driver' => 'oss',
'bucket' => 'my-bucket',
'endpoint' => 'oss-cn-hangzhou.aliyuncs.com',
'access_key_id' => 'your-access-key-id',
'access_key_secret' => 'your-access-key-secret',
],
],
];
// 使用
$disk = $filesystem->disk('oss');
$disk->put('file.txt', 'content');
腾讯云 COS
// 配置
return [
'disks' => [
'cos' => [
'driver' => 'cos',
'bucket' => 'my-bucket',
'region' => 'ap-guangzhou',
'secret_id' => 'your-secret-id',
'secret_key' => 'your-secret-key',
],
],
];
// 使用
$disk = $filesystem->disk('cos');
$disk->put('file.txt', 'content');
Google Cloud Storage
// 配置
return [
'disks' => [
'gcs' => [
'driver' => 'gcs',
'bucket' => 'my-bucket',
'key_file' => '/path/to/key.json',
'project_id' => 'your-project-id',
],
],
];
// 使用
$disk = $filesystem->disk('gcs');
$disk->put('file.txt', 'content');
Azure Blob Storage
// 配置
return [
'disks' => [
'azure' => [
'driver' => 'azure',
'container' => 'my-container',
'account_name' => 'your-account-name',
'account_key' => 'your-account-key',
],
],
];
// 使用
$disk = $filesystem->disk('azure');
$disk->put('file.txt', 'content');
文件操作
写入文件
// 写入文本内容
$disk->put('file.txt', 'content');
// 写入文件内容
$disk->put('file.txt', file_get_contents('/path/to/source.txt'));
// 追加内容
$disk->append('file.txt', 'additional content');
// 前置内容
$disk->prepend('file.txt', 'prefix content');
读取文件
// 读取文件内容
$content = $disk->get('file.txt');
// 检查文件是否存在
if ($disk->exists('file.txt')) {
$content = $disk->get('file.txt');
}
// 获取文件大小
$size = $disk->size('file.txt');
// 获取文件修改时间
$time = $disk->lastModified('file.txt');
删除文件
// 删除单个文件
$disk->delete('file.txt');
// 删除多个文件
$disk->delete(['file1.txt', 'file2.txt']);
// 删除目录
$disk->deleteDirectory('directory');
复制和移动
// 复制文件
$disk->copy('source.txt', 'destination.txt');
// 移动文件
$disk->move('source.txt', 'destination.txt');
// 重命名文件(使用 move)
$disk->move('old-name.txt', 'new-name.txt');
目录操作
// 创建目录
$disk->makeDirectory('directory');
// 列出目录内容
$files = $disk->files('directory');
$directories = $disk->directories('directory');
$all = $disk->allFiles('directory');
// 检查目录是否存在
if ($disk->exists('directory')) {
// 目录存在
}
获取 URL
// 获取文件 URL
$url = $disk->url('file.txt');
// 获取临时 URL(云存储)
$url = $disk->temporaryUrl('file.txt', now()->addMinutes(5));
文件上传
处理上传文件
namespace App\Index\Controller;
use Unicode\Framework\Http\Request;
use Unicode\Framework\Filesystem\FilesystemManager;
class UploadController
{
public function upload(Request $request): array
{
$file = $request->file('avatar');
if (!$file) {
return ['error' => 'No file uploaded'];
}
// 验证文件
$allowedTypes = ['image/jpeg', 'image/png'];
if (!in_array($file->getMimeType(), $allowedTypes)) {
return ['error' => 'Invalid file type'];
}
// 生成文件名
$filename = bin2hex(random_bytes(16)) . '.' . $file->getExtension();
$path = 'avatars/' . date('Y/m/d') . '/' . $filename;
// 保存文件
$filesystem = new FilesystemManager(Config::getInstance());
$disk = $filesystem->disk('local');
$disk->put($path, $file->getContents());
return [
'url' => $disk->url($path),
'path' => $path,
];
}
}
最佳实践
1. 文件命名
// ✅ 推荐:使用随机文件名
$filename = bin2hex(random_bytes(16)) . '.' . $extension;
// ❌ 错误:使用用户提供的文件名
$filename = $request->post('filename'); // 安全风险
2. 文件类型验证
// ✅ 推荐:验证文件类型和内容
$allowedTypes = ['image/jpeg', 'image/png'];
$mimeType = $file->getMimeType();
if (!in_array($mimeType, $allowedTypes)) {
return ['error' => 'Invalid file type'];
}
// 验证文件内容
$imageInfo = getimagesize($file->getPath());
if ($imageInfo === false) {
return ['error' => 'Invalid image'];
}
3. 文件大小限制
// ✅ 推荐:限制文件大小
$maxSize = 5 1024 1024; // 5MB
if ($file->getSize() > $maxSize) {
return ['error' => 'File too large'];
}
4. 存储路径组织
// ✅ 推荐:按日期组织文件
$path = 'uploads/' . date('Y/m/d') . '/' . $filename;
// 或按用户组织
$path = 'users/' . $userId . '/avatars/' . $filename;
5. 云存储配置
// ✅ 推荐:使用环境变量存储凭证
// .env
S3_KEY=your-access-key
S3_SECRET=your-secret-key
S3_BUCKET=my-bucket
S3_REGION=us-east-1
// config/filesystem.php
return [
'disks' => [
's3' => [
'driver' => 's3',
'key' => getenv('S3_KEY'),
'secret' => getenv('S3_SECRET'),
'bucket' => getenv('S3_BUCKET'),
'region' => getenv('S3_REGION'),
],
],
];
6. 文件缓存
// ✅ 推荐:缓存文件 URL
$cacheKey = 'file:url:' . $path;
$url = $cache->get($cacheKey, function() use ($disk, $path) {
return $disk->url($path);
}, 3600);
常见问题
Q: 如何切换存储驱动?
A: 在配置中设置 default 或使用 disk() 方法指定:
$disk = $filesystem->disk('s3');
Q: 云存储需要安装额外依赖吗?
A: 是的,需要在 composer.json 中安装对应的 SDK。
Q: 如何获取文件的公开 URL?
A: 使用 url() 方法:
$url = $disk->url('file.txt');
Q: 如何生成临时访问链接?
A: 使用 temporaryUrl() 方法(云存储支持):
$url = $disk->temporaryUrl('file.txt', now()->addMinutes(5));
Q: 文件系统接口是否统一?
A: 是的,所有存储驱动都实现 FilesystemInterface 接口,API 完全一致。