带有可选图像处理功能的 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 问题跟踪器报告。