yii2tech / file-storage
Yii2 文件存储抽象层
Requires
- yiisoft/yii2: ~2.0.13
README
Yii 2 文件存储扩展
此扩展为 Yii2 提供文件存储抽象层。
有关许可证信息,请查看 LICENSE 文件。
安装
安装此扩展的首选方式是通过 composer。
运行以下命令
php composer.phar require --prefer-dist yii2tech/file-storage
或
"yii2tech/file-storage": "*"
将其添加到你的 composer.json 文件的要求部分。
如果你想要使用 Amazon S3 存储,你还应该安装 aws/aws-sdk-php 版本 2。运行以下命令
php composer.phar require --prefer-dist aws/aws-sdk-php:~2.0
或
"aws/aws-sdk-php": "~2.0"
将其添加到你的 composer.json 文件的要求部分。
如果你想要使用 MongoDB 存储,你还应该安装 yiisoft/yii2-mongodb 版本 2.1。运行以下命令
php composer.phar require --prefer-dist yiisoft/yii2-mongodb:~2.1.0
或
"yiisoft/yii2-mongodb": "2.1.0"
将其添加到你的 composer.json 文件的要求部分。
用法
此扩展为 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访问文件
本扩展中实现的大多数文件存储实现都提供了通过网络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()]] 这样的方法保存或读取大于100MB的大文件时,可能会轻易超过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\*'], ], // ... ], ], ], ];