dfware/file-storage

Yii2 文件存储抽象层

资助包维护!
klimov-paul
Patreon

安装: 49

依赖: 1

建议: 0

安全: 0

星星: 0

关注者: 0

分支: 30

开放问题: 0

类型:yii2-extension

1.0.0 2023-09-27 17:52 UTC

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);

注意:您应该优先使用简单的模式如rw,避免使用复杂的模式如w+,因为某些存储可能不支持它们。

日志记录

文件存储组件执行的每个文件操作都会进行日志记录。为了设置一个可以捕获与文件存储相关的所有条目的日志目标,您应该使用分类yii2tech\filestorage\*。例如

return [
    // ...
    'components' => [
        // ...
        'log' => [
            // ...
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'logFile' => '@runtime/logs/file-storage.log',
                    'categories' => ['yii2tech\filestorage\*'],
                ],
                // ...
            ],
        ],
    ],
];