mycademy/ yii2-file-storage
为Yii2提供的文件存储抽象层
Requires
- yiisoft/yii2: ~2.0.13
README
此扩展为Yii2提供文件存储抽象层。
它是由https://github.com/yii2tech/file-storage的@klimov-paul分叉的。由于原始存储库已被归档,此分叉旨在继续开发并保持与其依赖项(例如aws-sdk-php)的新版本兼容。
有关许可信息,请参阅LICENSE文件。
安装
安装此扩展的首选方法是使用composer。
运行以下命令之一:
php composer.phar require --prefer-dist mycademy/yii2-file-storage
或者添加以下内容到您的composer.json文件的require部分:
"mycademy/yii2-file-storage": "*"
如果您想使用Amazon S3存储,您还应该安装aws/aws-sdk-php版本2。运行以下命令:
php composer.phar require --prefer-dist aws/aws-sdk-php:~2.0
或者添加以下内容到您的composer.json文件的require部分:
"aws/aws-sdk-php": "~3.172"
如果您想使用MongoDB存储,您还应该安装yiisoft/yii2-mongodb版本2.1。运行以下命令:
php composer.phar require --prefer-dist yiisoft/yii2-mongodb:~2.1.0
或者添加以下内容到您的composer.json文件的require部分:
"yiisoft/yii2-mongodb": "2.1.0"
使用方法
此扩展为Yii2提供文件存储抽象层。此抽象引入了两个主要术语:“存储”和“存储桶”。“存储”是指能够使用某种特定方法存储文件的单元。“存储桶”是存储的逻辑部分,具有自己的特定属性并服务于某些逻辑目的。每次需要读取/写入文件时,都应该通过特定的存储桶进行,该存储桶始终属于文件存储。
示例应用程序配置
return [ 'components' => [ 'fileStorage' => [ 'class' => 'mycademy\yii2filestorage\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'
此扩展提供了以下文件存储:
- [[\mycademy\yii2filestorage\local\Storage]] - 在OS本地文件系统中存储文件。
- [[\mycademy\yii2filestorage\sftp\Storage]] - 使用SSH2 SFTP存储文件。
- [[\mycademy\yii2filestorage\amazon\Storage]] - 使用Amazon简单存储服务(S3)存储文件。
- [[\mycademy\yii2filestorage\mongodb\Storage]] - 使用MongoDB GridFS存储文件。
- [[\mycademy\yii2filestorage\hub\Storage]] - 允许组合不同的文件存储。
请参阅特定存储类的文档以获取更多详细信息。
请注意!某些存储可能需要安装默认不包含此包的附加库或PHP扩展。请检查特定存储类的文档以获取详细信息。
抽象使用
每个提供的存储都实现了用于文件处理的相同接口。因此,每个存储都可以替代另一个,除非程序代码遵循此接口。这允许您在无需调整程序源代码的情况下在存储之间切换。例如,在生产服务器上,您可能需要使用SFTP进行文件存储,并且应用程序配置如下所示:
return [ 'components' => [ 'fileStorage' => [ 'class' => 'mycademy\yii2filestorage\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' => 'mycademy\yii2filestorage\local\Storage', 'basePath' => '@webroot/files', 'baseUrl' => '@web/files', 'buckets' => [ 'temp', 'item', ] ], // ... ], // ... ];
您也可以指定一个与内部名称不同的存储桶名称。在下面的示例中,存储桶通过Wii::$app->fileStorage->getBucket('images');
检索,但将存储在my-image-bucket
存储桶中。
return [ 'components' => [ 'fileStorage' => [ 'class' => 'mycademy\yii2filestorage\amazon\Storage', 'buckets' => [ 'buckets' => [ 'images' => [ 'name' => 'my-image-bucket', 'region' => 'us-west-1', ], ], ] ], // ... ], // ... ];
如果需要,您还可以使用[[\mycademy\yii2filestorage\hub\Storage]]组合几个不同的存储
return [ 'components' => [ 'fileStorage' => [ 'class' => 'mycademy\yii2filestorage\hub\Storage', 'storages' => [ [ 'class' => 'mycademy\yii2filestorage\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' => 'mycademy\yii2filestorage\local\Storage', 'basePath' => '@webroot/files', 'baseUrl' => '@web/files', 'buckets' => [ 'temp', ] ] ], ], // ... ], // ... ];
通过URL访问文件
几乎所有文件存储实现,在这个扩展中实现,都提供了通过Web URL访问存储文件的机制。实际机制实现可能因特定存储而异。例如:[[\mycademy\yii2filestorage\local\Storage]] 允许设置指向其根目录的URL,为特定文件创建URL,将文件名附加到基本URL上,而 [[\mycademy\yii2filestorage\amazon\Storage]] 使用S3内置对象URL组合。
为了获取指向存储文件的URL,您应使用 [[\mycademy\yii2filestorage\BucketInterface::getFileUrl()]] 方法
$bucket = Yii::$app->fileStorage->getBucket('tempFiles'); $fileUrl = $bucket->getFileUrl('image.jpg');
如果特定存储不支持原生的URL文件访问,或者由于某种原因不可用或不希望使用,您可以通过Yii URL路由机制设置文件URL的组成。您需要设置 baseUrl
为一个数组,包含指向将返回文件内容的Yii控制器动作的路由。例如
return [ 'components' => [ 'fileStorage' => [ 'class' => 'mycademy\yii2filestorage\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`
您可以将 [[\mycademy\yii2filestorage\DownloadAction]] 设置为处理文件内容Web访问。例如
class FileController extends \yii\web\Controller { public function actions() { return [ 'download' => [ 'class' => 'mycademy\yii2filestorage\DownloadAction', ], ]; } }
提示:通常,用于文件Web访问的控制器动作比文件存储提供的原生机制慢,但是您可以在其中放入一些额外的逻辑,例如仅允许已登录用户访问文件。
处理大文件
使用 [[\mycademy\yii2filestorage\BucketInterface::saveFileContent()]] 或 [[\mycademy\yii2filestorage\BucketInterface::getFileContent()]] 等方法保存或读取大于100 MB的大文件时,可能轻易超过PHP内存限制,破坏脚本。您应使用 [[\mycademy\yii2filestorage\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+
,因为它们可能不被某些存储支持。
日志记录
文件存储组件执行的所有文件操作都会进行日志记录。为了设置可以捕获与文件存储相关的所有条目的日志目标,您应使用类别 mycademy\yii2filestorage\*
。例如
return [ // ... 'components' => [ // ... 'log' => [ // ... 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'logFile' => '@runtime/logs/file-storage.log', 'categories' => ['mycademy\yii2filestorage\*'], ], // ... ], ], ], ];