带有可选图像处理功能的 FileStorage 插件

此插件使您能够将文件存储在几乎任何类型的存储后端。此插件以 CakePHP 方式包装了 Gaufrette 库 (https://github.com/KnpLabs/Gaufrette),并提供了一种简单的方法来通过 StorageManager 类使用存储适配器。存储适配器是一种统一的接口,允许您将文件数据存储到本地文件系统、内存、数据库或压缩文件以及远程系统中。有一个数据库表跟踪您存储的内容。

适配器

通过 Gaufrette 供应商库包含的存储适配器是

Local File System
Amazon S3
ACL Aware Amazon S3
Mogile FS
Rackspace Cloudfiles
Zip File
Ftp
Sftp
In Memory
Grid FS
Apc
Doctrine DBAL

您始终可以编写自己的适配器或扩展和覆盖现有适配器。

StorageManager::config('Local', array(
    'adapterOptions' => array(TMP, true),
    'adapterClass' => '\Gaufrette\Adapter\Local',
    'class' => '\Gaufrette\Filesystem'));

0 要配置适配器,请使用 StorageManager::config 方法。第一个参数是配置的名称,第二个参数是该适配器的选项数组 B0x1A1 要使用之前设置的配置调用来调用新实例

$Adapter = StorageManager::adapter('Local');

您也可以像这样调用适配器实例的方法

StorageManager::adapter('Local')->write($key, $data);

或者,您可以将配置数组作为第一个参数传递给 get 实例,以使用不在配置中的这些设置。

要删除配置,并因此删除 StorageManager 中的实例,请调用

StorageManager::flush('Local');

如果您要刷新 *所有* 适配器配置和实例,只需不带第一个参数调用它即可。

如何存储上传的文件

此插件的基本理念是文件始终作为单独的实体处理,并与其他模型相关联。

例如,假设您有一个 Report 模型,并且想要将一个 pdf 保存到它,那么您将创建一个关联,例如

public $hasOne = array(
    'PdfFile' => array(
        'className' => 'FileStorage.FileStorage',
        'foreignKey' => 'foreign_key'));

在添加/编辑报告中,您将拥有类似以下内容

echo $this->Form->input('Report.title');
echo $this->Form->input('PdfFile.file');
echo $this->Form->input('Report.description');

现在是整个实现的关键点

由于存在太多不同的需求和个人偏好,插件 *不会* 自动存储文件。您需要对其进行一些自定义,但这只是几行代码的问题。

让我们以报告模型中的这种情况为例,假设有一个 add() 方法

$this->create()
if ($this->save($data)) {
    $key = 'your-file-name';
    if (StorageManager::adapter('Local')->write($key, file_get_contents($this->data['PdfFile']['tmp_name']))) {
        $this->data['PdfFile']['foreignKey'] = $this->getLastInsertId();
        $this->data['PdfFile']['model'] = 'Report';
        $this->data['PdfFile']['path'] = $key;
        $this->data['PdfFile']['adapter'] = 'Local';
    }
}

稍后,当您想要删除文件时,例如在 Report 模型的 beforeDelete() 或 afterDelete() 回调中,您将知道用于存储附加 PdfFile 的适配器,并且可以使用 StorageManager 获取此适配器配置的实例。通过获得路径或键,您可以简单地调用

StorageManager::adapter($data['PdfFile']['adapter'])->delete($data['PdfFile']['path']);

除了在与文件相关联的模型中执行所有这些操作外,您还可以简单地扩展插件中的 FileStorage 模型,并在其中添加存储逻辑,并使用该模型进行关联。

为什么要这样做?

因为每个开发人员都可能希望在不同的时间点存储文件,或者在存储文件之前或之后对文件执行其他操作。根据不同的情况,您可能希望在创建要附加到的记录之前甚至保存关联的文件,在其他情况下,例如在本文档中,您希望在创建后保存文件。

$key 也是一个关键方面:不同的适配器可能需要不同的键。Local 适配器的键通常是路径和文件名,数据将在其中存储。另一个适配器可能需要 UUID。这也是您使用 file_get_contents() 而不是简单地传递 tmp 路径的原因。

下载

您可以从 https://github.com/burzum/FileStorage 获取插件

我认为它很稳定,我已经使用它一段时间了,没有出现问题,我们在内部 CakeDC 项目中也使用了它,没有出现问题,到目前为止,我还没有收到 13 个关注者中任何一个的错误报告。

如果您发现错误或有任何建议,请使用 git 问题跟踪器报告。