dfware / file-storage
Yii2 文件存储抽象层
Requires
- yiisoft/yii2: ~2.0.13
This package is auto-updated.
Last update: 2024-09-27 20:06:11 UTC
README
安装此扩展的首选方式是通过 composer。
运行以下命令:
composer require dfware/file-storage
或者在您的 composer.json 文件的要求部分添加:
"dfware/file-storage": "*"
到
如果您想使用 Amazon S3 存储空间,还应安装 aws/aws-sdk-php 版本 2。运行以下命令:
php composer.phar require --prefer-dist aws/aws-sdk-php:~2.0
或者在您的 composer.json 文件的要求部分添加:
"aws/aws-sdk-php": "~2.0"
到
如果您想使用 MongoDB 存储空间,还应安装 yiisoft/yii2-mongodb 版本 2.1。运行以下命令:
php composer.phar require --prefer-dist yiisoft/yii2-mongodb:~2.1.0
或者在您的 composer.json 文件的要求部分添加:
"yiisoft/yii2-mongodb": "2.1.0"
到
用法
此扩展为 Yii2 提供文件存储抽象层。这种抽象引入了两个主要术语:“存储”和“存储桶”。“存储” - 是一个单位,可以使用某种特定的方法存储文件。“存储桶” - 是存储的逻辑部分,具有自己特定的属性并服务于某些逻辑功能。每次需要读取/写入文件时,都应该通过特定的存储桶进行,该存储桶始终属于文件存储。
示例应用程序配置
return [ 'components' => [ 'fileStorage' => [ 'class' => 'yii2tech\filestorage\local\Storage', 'basePath' => '@webroot/files', 'baseUrl' => '@web/files', 'dirPermission' => 0775, 'filePermission' => 0755, 'buckets' => [ 'tempFiles' => [ 'baseSubPath' => 'temp', 'fileSubDirTemplate' => '{^name}/{^^name}', ], 'imageFiles' => [ 'baseSubPath' => 'image', 'fileSubDirTemplate' => '{ext}/{^name}/{^^name}', ], ] ], // ... ], // ... ];
示例用法
$bucket = Yii::$app->fileStorage->getBucket('tempFiles'); $bucket->saveFileContent('foo.txt', 'Foo content'); // create file with content $bucket->deleteFile('foo.txt'); // deletes file from bucket $bucket->copyFileIn('/path/to/source/file.txt', 'file.txt'); // copy file into the bucket $bucket->copyFileOut('file.txt', '/path/to/destination/file.txt'); // copy file from the bucket var_dump($bucket->fileExists('file.txt')); // outputs `true` echo $bucket->getFileUrl('file.txt'); // outputs: 'http://domain.com/files/f/i/file.txt'
此扩展提供以下文件存储:
- [[\yii2tech\filestorage\local\Storage]] - 在 OS 本地文件系统上存储文件。
- [[\yii2tech\filestorage\sftp\Storage]] - 使用 SSH2 SFTP 存储文件。
- [[\yii2tech\filestorage\amazon\Storage]] - 使用 Amazon 简单存储服务(S3)存储文件。
- [[\yii2tech\filestorage\mongodb\Storage]] - 使用 MongoDB GridFS 存储文件。
- [[\yii2tech\filestorage\hub\Storage]] - 允许组合不同的文件存储。
请参阅特定存储类的文档以获取更多详细信息。
注意!某些存储可能需要安装默认不包含此包的附加库或 PHP 扩展。请检查特定存储类的文档以获取详细信息。
抽象用法
每个提供的存储都实现了相同的接口以处理文件。因此,除非程序代码遵循此接口,否则每个存储都可以替换另一个存储。这允许您在不调整程序源代码的情况下在不同的存储之间进行切换。例如,在生产服务器上,您可能需要使用 SFTP 来存储文件,并且您的应用程序配置如下所示
return [ 'components' => [ 'fileStorage' => [ 'class' => 'yii2tech\filestorage\sftp\Storage', 'ssh' => [ 'host' => 'file.server.com', 'username' => 'user', 'password' => 'some-password', ], 'basePath' => '/var/www/html/files', 'baseUrl' => 'http://file.server.com/files', 'buckets' => [ 'temp', 'item', ] ], // ... ], // ... ];
然而,在开发环境中,您可以使用简单的本地文件存储代替
return [ 'components' => [ 'fileStorage' => [ 'class' => 'yii2tech\filestorage\local\Storage', 'basePath' => '@webroot/files', 'baseUrl' => '@web/files', 'buckets' => [ 'temp', 'item', ] ], // ... ], // ... ];
如果需要,您也可以使用 [[\yii2tech\filestorage\hub\Storage]] 结合几个不同的存储
return [ 'components' => [ 'fileStorage' => [ 'class' => 'yii2tech\filestorage\hub\Storage', 'storages' => [ [ 'class' => 'yii2tech\filestorage\sftp\Storage', 'ssh' => [ 'host' => 'file.server.com', 'username' => 'user', 'password' => 'some-password', ], 'basePath' => '/var/www/html/files', 'baseUrl' => 'http://file.server.com/files', 'buckets' => [ 'item', ] ], [ 'class' => 'yii2tech\filestorage\local\Storage', 'basePath' => '@webroot/files', 'baseUrl' => '@web/files', 'buckets' => [ 'temp', ] ] ], ], // ... ], // ... ];
通过 URL 访问文件
此扩展中实现的几乎所有文件存储实现都提供了通过 Web URL 访问存储文件的功能。实际机制实现可能因特定存储而异。例如:[[\yii2tech\filestorage\local\Storage]] 允许设置指向其根目录的 URL,通过将文件名附加到基本 URL 创建特定文件的 URL,而 [[\yii2tech\filestorage\amazon\Storage]] 使用 S3 内置的对象 URL 组合。
要获取指向存储文件的 URL,您应使用 [[\yii2tech\filestorage\BucketInterface::getFileUrl()]] 方法
$bucket = Yii::$app->fileStorage->getBucket('tempFiles'); $fileUrl = $bucket->getFileUrl('image.jpg');
如果特定的存储不提供本机URL文件访问,或者由于某种原因不可用或不可取,您可以通过Yii URL路由机制设置文件URL的组成。您需要将baseUrl
设置为包含路由的数组,该路由指向将返回文件内容的Yii控制器操作。例如
return [ 'components' => [ 'fileStorage' => [ 'class' => 'yii2tech\filestorage\local\Storage', 'baseUrl' => ['/file/download'], // ... ], // ... ], // ... ];
在这种配置下,getFileUrl()
方法将使用当前应用程序的URL管理器来创建URL。这样做,它将添加桶名称作为bucket
参数和文件名作为filename
参数。例如
use yii\helpers\Url; $bucket = Yii::$app->fileStorage->getBucket('images'); $fileUrl = $bucket->getFileUrl('logo.png'); $manualUrl = Url::to(['/file/download', 'bucket' => 'images', 'filename' => 'logo.png']); var_dump($fileUrl === $manualUrl); // outputs `true`
您可以将[[\yii2tech\filestorage\DownloadAction]]设置为处理文件内容的网络访问。例如
class FileController extends \yii\web\Controller { public function actions() { return [ 'download' => [ 'class' => 'yii2tech\filestorage\DownloadAction', ], ]; } }
提示:对于文件网络访问,控制器操作通常比文件存储提供的本机机制慢,但是您可以在其中放入一些额外的逻辑,例如仅允许登录用户访问文件。
大文件的处理
使用像[[\yii2tech\filestorage\BucketInterface::saveFileContent()]]或[[\yii2tech\filestorage\BucketInterface::getFileContent()]]这样的方法保存或读取大于100 MB的大文件,可能很容易超过PHP内存限制,从而破坏脚本。您应该使用[[\yii2tech\filestorage\BucketInterface::openFile()]]方法创建一个类似于通过[[fopen()]] PHP函数创建的文件资源。这种资源可以通过块读取或写入,保持内存使用量低。例如
$bucket = Yii::$app->fileStorage->getBucket('tempFiles'); $resource = $bucket->openFile('new_file.dat', 'w'); fwrite($resource, 'content part1'); fwrite($resource, 'content part2'); // ... fclose($resource); $resource = $bucket->openFile('existing_file.dat', 'r'); while (!feof($resource)) { echo fread($resource, 1024); } fclose($resource);
注意:您应该优先使用简单的模式如
r
和w
,避免使用复杂的模式如w+
,因为某些存储可能不支持它们。
日志记录
文件存储组件执行的每个文件操作都会进行日志记录。为了设置一个可以捕获与文件存储相关的所有条目的日志目标,您应该使用分类yii2tech\filestorage\*
。例如
return [ // ... 'components' => [ // ... 'log' => [ // ... 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'logFile' => '@runtime/logs/file-storage.log', 'categories' => ['yii2tech\filestorage\*'], ], // ... ], ], ], ];