文件系统

最后更新: 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 完全一致。

相关文档