【问题标题】:PHP MongoDB PDF Upload blob IssuePHP MongoDB PDF上传blob问题
【发布时间】:2014-11-18 14:13:03
【问题描述】:

我允许用户上传 image/doc 文件,为此我正在使用 MongoDB GridFS 。我可以上传有限大小的images, doc files and pdf(大约5 MB)并根据需要存储(单个条目),然后用于获取数据并在前端显示。

上传文件的代码如下

$conn = new MongoClient();
$db = $conn->selectDB('mydb');
$gridfs = $db->getGridFS('uploads');

$ObjId = new MongoId();
$uniqId = (string)$ObjId;

$uploadedIds = array();

foreach ($_FILES as $file) {
    $id = $gridfs->storeFile($file['tmp_name'], array("metadata" => array(
        'filename' => $file['name'],
        'type' => $file['type'],
        "id"=> 2,
        "parentId" => "1",
        "name" => "Employee Reference",
        "title" => "Employee Reference",
        "isFolder" => 1
    )));

    $id = $gridfs->storeFile($file['tmp_name'], array(
        '_id' => $ObjId,
        "id" => $uniqId,
        'filename' => $file['name'],
        'type' => $file['type'],
        "parentId" => "10",
        "title" => $file['name'], 
        isFolder" => 0
    ));
}

$conn->close();

但是当我尝试上传大小约为8 MBPDF 时,它会以以下格式存储数据。

{
    "_id" : ObjectId("54226f4c920662240a000080"),
    "filename" : "blob",
    "type" : "application/octet-stream",
    "title" : "blob",
    "uploadDate" : ISODate("2014-09-24T07:14:20.000Z"),
    "length" : 338277,
    "chunkSize" : 261120,
    "md5" : "d4f9269491c30a0ab086b3bab02c81ee"
}

正如您在上面看到的,文件根据length 进行划分,对于单个PDF,它会插入8 周围的条目。

如何将大文件的数据合二为一,并在前端显示文件名和其他详细信息?

谢谢。

【问题讨论】:

  • 你用的是什么库?无论您是使用库还是单独使用 PHP 驱动程序,共享负责存储文件的代码的 sn-p 都会很有帮助。 “单项”很奇怪,因为默认的块大小是 256k。此外,考虑到 GridFS 的工作方式,即使是最小的文件也将包含两个文档:fs.filesfs.chunks 各一个(注意:fs 可以自定义)。
  • @jmikola,我已经添加了上传代码。 fs.filefs.chunks 没问题,但 fs.files 有多个插入条目。

标签: php mongodb gridfs


【解决方案1】:

没有理由对同一个文件多次调用storeFile()。这将创建一个额外的fs.files 文档和冗余的fs.chunks 文档。

在您第一次调用storeFile() 时,您将所有元数据嵌套在metadata 字段下,这可能不是您想要的。 GridFS 存储方法的$metadata 参数本质上合并到将要创建的fs.files 文档中,这就是为什么文档提到在$metadata 中使用_id(如果提供的话)的原因;否则,驱动程序会生成一个新的 MongoId 实例。第二次调用 storeFile() 时的 $metadata 参数看起来更典型。

由于您在元数据数组中包含 isFolder 字段,我认为您可能错误地假设 GridFS 支持目录结构。 GridFS 只不过是各种驱动程序共享的一种约定,用于在集合中存储二进制 blob。 fs.files 记录保存元数据(核心字段概述为here),所有二进制数据都存储在一个或多个相关的fs.chunks 文档中(链接回fs.files 标识符)。

可以通过元数据字段使用 GridFS 模拟目录结构,但这不是一个常用功能。例如,您可以添加一个path 元数据字段,该字段将始终存储规范的目录路径(例如,您的应用程序将在存储之前将/foo/bar/../bar 标准化为/foo/bar),然后创建一个fs.files 的索引,需要@ 987654343@ 和 filename 组合是唯一的。跟踪这完全取决于您的应用程序。


由于您要存储上传的文件(在$_FILES 中引用),您可能希望使用MongoGridFS::storeUpload(),它将字段名称(即$_FILES 键)作为其第一个参数并自动填充@987654348 fs.files 文档中的 @ 字段基于用户提供的名称。通常,客户端文件名是任意的(所以不要盲目相信它或期望它是唯一/准确的);但是,如果您打算在 UI 中将其显示给用户,则值得存储。

作为最后的想法,通常没有理由在脚本末尾调用MongoClient::close()。文档甚至反对它,因为它破坏了驱动程序管理持久连接的能力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 2020-01-25
    • 1970-01-01
    • 2011-08-04
    • 2018-12-07
    • 2015-08-22
    • 1970-01-01
    相关资源
    最近更新 更多