2013-06-15 2 views
1

Недавно мы интегрировали Gridfs в mongodb для хранения изображений. Для моего требования ранее мы использовали NFS для получения или хранения изображений в каталоге. его становится все медленнее для изображений. Поэтому мы интегрировали GridFS.Gridfs in mongodb

GridFS, но теперь мое уточнение заключается в том, как мы можем получить изображения более одного раза по одному запросу и показать их в браузере ?. Потому что мы заполнили около 1L фотографий в mongodb gridfs sharding. Но я не могу получить более одного изображения по одному запросу.

Образец кода, приведенный ниже. - Следующий код вернет только одну фотографию. Я не могу получить все изображения по одному запросу. Если кто-то сталкивается с такими проблемами, PLS поделится нами.

Способ 1: Он возвращает только одно изображение.

$mongo = new Mongo("192.168.0.8:27017"); 
$db = $mongo->myfiles; 
$gridFS = $db->getGridFS(); 
$cursor = $gridFS->find()->limit(10); - it will return one than one images 
/*$cursor = $gridFS->find(array("metadata.memberid"=>"CMD34123")); - it will return one than one images, because the member having more than one images.*/ 

foreach ($cursor as $obj) 
{     
     header("Content-Type: image/jpg"); 
     $stream = $obj->getResource(); 

     while (!feof($stream)) { 
       echo fread($stream, 51200); 
     } 
} 

Метод 2: Он возвращает все изображения, но это же, как NFS каждое изображение будет получать каждый запрос HTTP. Нет экономии.

$mongo = new Mongo("192.168.0.8:27017"); 
$db = $mongo->myfiles; 
$gridFS = $db->getGridFS(); 
$cursor = $gridFS->find()->limit(10); 
foreach ($cursor as $obj) 
     echo "<img src='getphoto.php?filename=".$obj->getFilename()."'>"; 

getphoto.php:

$mongo = new Mongo("192.168.0.8:27017"); 
$db = $mongo->myfiles; 
$gridFS = $db->getGridFS(); 
/*$image = $gridFS->findOne($_REQUEST['filename']);*/ 
header("Content-Type: image/jpg"); 
echo $stream = $image->getResource(); 
while (!feof($stream)) 
     echo fread($stream, 51200); 

ответ

2

Я не вижу, как вы могли бы возвращать несколько файлов в одном запросе, если вы не использовали один из РНР compression and archive extensions, чтобы объединить их в один файл , который, в свою очередь, был передан как ответ HTTP.

Если изображения небольшие, альтернатива будет включать их в HTML как base64-encoded Data URIs. Этот метод часто используется для встраивания небольших изображений (размер значков) в значения CSS background-image; однако он не подходит для больших изображений, поскольку накладные расходы на хранение довольно высоки.


Что касается этого запроса в первом примере кода:

$gridFS->find(array("metadata.memberid"=>"CMD34123")) 

Я понимаю, что эта линия комментировали, но если вы работаете такой запрос, я хотел бы предложить индексацию metadata.memberid, чтобы избежать сканирования каждого документа в коллекции fs.files.

Итерация, которую вы делали, пытается напечатать заголовок и содержимое байта содержимого несколько JPG изображения подряд. Таким образом, функция PHP header() не может быть вызвана несколькими раз.

Возможно, вы можете использовать multi-part HTTP responses для отправки нескольких изображений, но поддержка браузера может быть проблематичной (см.: this question from a few years back).


В вашем getphoto.php источнике, вы намерены вызвать MongoGridFS::findOne() с параметром строки. Вы должны знать, что пользователи могут использовать строку запроса так, чтобы $_REQUEST['filename'] был фактически массивом (см.: this post on the subject). Вам следовало бы проверить параметр запроса и/или передать его в строку, прежде чем передать ее на findOne().

Дополнительно:

  • Это будет запрос на filename поле, так что вы должны убедиться, что он индексируется.
  • В поле fs.filesspecification поле filename является необязательным и необязательно уникальным. Вполне возможно, что несколько файлов в GridFS могут иметь одинаковое имя файла.

С учетом вышеуказанных пунктов, он может быть проще просто использовать 24 шестнадцатеричных символов из ObjectId в качестве параметра запроса, построить MongoId и запрос с, что на _id поле (или используйте MongoGridFS::get()). Мои предыдущие пункты по проверке параметра запроса все равно будут стоять в этом случае - это позволит вам использовать индекс _id по умолчанию.

Смежные вопросы