我允许用户上传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 MB
的PDF
时,它会以以下格式存储数据。
{
"_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
个条目。
如何在一个文件中获取大文件的数据,并在前端显示文件名和其他详细信息?
谢谢。
没有理由在同一文件上多次调用storeFile()
。这将创建一个额外的fs.files
文档和冗余的fs.chunks
文档。
在对storeFile()
的第一次调用中,您将所有元数据嵌套在metadata
字段下,这可能不是您想要的。GridFS存储方法的$metadata
自变量基本上被合并到将要创建的fs.files
文档中,这就是为什么该文档暗示在$metadata
中使用_id
(如果提供的话);否则,驱动程序将生成一个新的MongoId实例。对storeFile()
的第二次调用中的$metadata
参数看起来更为典型。
由于您在元数据数组中包含了一个isFolder
字段,我认为您可能错误地认为GridFS支持目录结构。GridFS不过是一种约定,由各种驱动程序共享,用于在集合中存储二进制Blob。fs.files
记录保存元数据(此处概述了核心字段),所有二进制数据存储在一个或多个相关的fs.chunks
文档中(链接回fs.files
标识符)。
可以通过元数据字段的方式用GridFS模拟目录结构,但这不是一个常用功能。例如,您可以添加一个path
元数据字段,该字段将始终存储规范的目录路径(例如,您的应用程序将在存储之前将/foo/bar/../bar
规范化为/foo/bar
),然后创建一个要求path
和filename
组合唯一的fs.files
索引。这将完全取决于您的应用程序来跟踪这一点。
由于您正在存储上传的文件(在$_FILES
中引用),因此可能需要使用MongoGridFS::storeUpload()
,它将字段名(即$_FILES
键)作为第一个参数,并根据用户提供的名称自动填充fs.files
文档中的filename
字段。通常,客户端文件名是任意的(所以不要盲目相信它或期望它是唯一/准确的);但是,如果您计划在UI中向用户显示它,那么它是值得存储的。
最后,通常没有理由在脚本末尾调用MongoClient::close()。文档甚至建议不要这样做,因为它会削弱驱动程序管理持久连接的能力。