Я разрешаю пользователю загружать 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();
Но когда я пытаюсь загрузить PDF
с размером вокруг 8 MB
, он хранит данные в следующем формате.
{
"_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
поле, которое, скорее всего, не то, что вы хотите. $metadata
Аргумент к методам хранения GridFS по существу объединен в fs.files
документ, который будет создан, поэтому в документации упоминается использование _id
в $metadata
если один предоставляется; в противном случае драйвер генерирует новый экземпляр MongoId. $metadata
аргумент в вашем втором звонке storeFile()
выглядит более типично.
Так как вы включаете isFolder
поле в ваших массивах метаданных, я думаю, вы могли бы ошибочно предполагать, что GridFS поддерживает структуру каталогов. GridFS — это не что иное, как соглашение, разделяемое различными драйверами, для хранения двоичных двоичных объектов в коллекции. fs.files
метаданные хранения записей (основные поля выделены Вот) и все двоичные данные хранятся в одном или нескольких связанных fs.chunks
документы (связанные с fs.files
идентификатор).
Можно моделировать структуру каталогов с помощью GridFS с помощью полей метаданных, но это не стандартная функция. Например, вы можете добавить path
поле метаданных, которое всегда будет хранить канонический путь к каталогу (например, ваше приложение нормализуется /foo/bar/../bar
как /foo/bar
до хранения), а затем создать индекс fs.files
требуя path
а также filename
комбинация, чтобы быть уникальной. Это будет зависеть от вашего приложения, чтобы отслеживать это.
Так как вы храните загруженный файл (упоминается в $_FILES
), вы можете использовать MongoGridFS::storeUpload()
, который принимает имя поля (т.е. $_FILES
ключ) в качестве первого аргумента и автоматически заполняет filename
поле в fs.files
документ на основе имени, предоставленного пользователем. Как правило, имя файла на стороне клиента является произвольным (поэтому не следует слепо доверять ему или ожидать, что оно будет уникальным / точным); однако, стоит сохранить, если вы планируете показать его пользователю в вашем пользовательском интерфейсе.
Как последняя мысль, вообще нет причин звонить MongoClient :: близко () в конце вашего сценария. Документация даже не советует этого, так как это наносит ущерб способности водителя управлять постоянными соединениями.
Других решений пока нет …