GridFS是MongoDB的一个内置功能,它提供一组文件操作的API以利用MongoDB存储文件,GridFS的基本原理是将文件保存在两个Collection中,一个保存文件索引,一个保存文件内容,文件内容按一定大小分成若干块,每一块存在一个Document中,这种方法不仅提供了文件存储,还提供了对文件相关的一些附加属性(比如MD5值,文件名等等)的存储。 初始化gridfs $conn=newMongo();//连接MongoDB $db=$conn->photos;//选择数据库 $collection=$db->getGridFS();//取得gridfs对象 gridfs有三种方式存储文件 第一种直接存储文件 $id=$collection->storeFile("./logo.png"); 第二种存储文件二进制流 $data=get\_file\_contents("./logo.png"); $id=$collection->storeBytes($data,array("param"=>'附加参数将随图片一起存入')); 第三种保存直接表单提交的文件$\_FILES $id=$collection->storeUpload('upfile'); 相当于 $id=$collection->storeFile($\_FILES\['upfile'\]\['tmp\_name'\]); //--------------以上是保存图片--下面开始读取图片---------------- 保存成功后返回$id = md5字符串 $logo=$collection->findOne(array('\_id'=>$id));// 以\_id为索引取得文件 header('Content-type:image/png');//输出图片头 echo$logo->getBytes();//输出数据流 ?> **特别备注:** 通过$id = $collection->storeFile($\_FILES\['upfile'\]\['tmp\_name'\]);产生的ID,是MongoDB的ID对象,而不是一个字符串!如以下格式: { "\_id": ObjectId("525418525ba8a18c1b000001"), "filename":"D:\\\\php\\\\xampp\\\\tmp\\\\php8116.tmp", "uploadDate": ISODate("2013-10-08T14:36:02.0Z"), "length": NumberInt(55862), "chunkSize": NumberInt(262144), "md5":"a6f19f3434f0b36bb2611cd4c6d82b35" } 不过,我们可以通过$id = strval($id),把上述ID对象字符串化,如可得到上述的525418525ba8a18c1b000001值,再把这个值存到MySQL数据库中,到时候可通过这个 字符串ID 作为条件,找到相应的MongoDB资源。参考代码如下: $conn=newMongo(C('127.0.0.1:27017'));//如果设置了密码自己配置DSN $db=$conn->selectDB('edu\_sns');// 选择数据库 $collection=$db->getGridFS('zk\_attach');//选择集合,相等于选择数据表 $id=$\_GET\['id'\]; $object=$collection->findOne(array('\_id'=>newMongoId($id))); header('Content-type:image/png'); echo$object->getBytes(); **最近因工作需要研究了下GridFS,并整理了个Demo出来。。分享一下经验。。** **gfs.php文件** //连接Mongo并初始化GFS $conn=newMongo(C('127.0.0.1:27017'));//如果设置了密码自己配置DSN $db=$conn->selectDB('edu\_sns');//选择数据库 $collection=$db->getGridFS('zk\_attach');//选择集合,相等于选择数据表 //上传图片 if(isset($\_FILES\['upfile'\])) { 保存新上传的文件 $size=$\_FILES\['upfile'\]\['size'\]; $md5= md5\_file($\_FILES\['upfile'\]\['tmp\_name'\]); $exists=$collection->findOne(array('md5'=>$md5,'length'=>$size),array('md5')); if(empty($exists)) { 15$collection->storeUpload('upfile'); //或修改为如下代码,并存入一些自定义参数 /\* $filename=$\_FILES\['upfile'\]\['name'\]; $filetype=$\_FILES\['upfile'\]\['type'\]; $tmpfilepath=$\_FILES\['upfile'\]\['tmp\_name'\]; $id=$gridfs->storeFile($tmpfilepath, array('filename' => $filename, 'filetype' => $filetype)); \*/ }else{ unlink($\_FILES\['upfile'\]\['tmp\_name'\]); } echo" 图片路径为: http://{$\_SERVER\['HTTP\_HOST'\]}{$\_SERVER\['REQUEST\_URI'\]}?img={$md5}"; }elseif($id=$\_GET\['img'\]) { //生成图片 //索引图片文件 $image=$collection->findOne(array('md5'=>$id)); //设定文档类型,显示图片 $img\_bytes=$image->getBytes(); include\_once'thumb.php'; $w=is\_numeric($\_GET\['w'\]) ?intval($\_GET\['w'\]): 100; Thumb::maxWidth($img\_bytes,$w); }elseif($id=$\_GET\['del'\]) {//删除图片 $s=$collection->remove(array('md5'=>$id)); 43header('Location:'.$\_SERVER\['HTTP\_REFERER'\]); 44 45}else{// 图片列表 46$cursor=$collection->find(); 47foreach($cursoras$obj) : 48echo' href="?img='.$obj->file\['md5'\] .'&w=800"> src="?img='.$obj->file\['md5'\] .'" border="0" /> .'">删除'; 49endforeach 50; 51} 52?> **thumb.php 缩略图文件** 001 002classThumb { 003 004/\*\* 005\* 以最大宽度缩放图像 006\* 007\* @param string $im 图像元数据 008\* @param float $w 最大宽度 009\*/ 010staticfunctionmaxWidth($im,$w) { 011if(empty($im) ||empty($w) || !is\_numeric($w)) { 012thrownewException("缺少必须的参数"); 013} 014$im= imagecreatefromstring($im);// 创建图像 015list ($im\_w,$im\_h) \= self::getsize($im);// 获取图像宽高 016if($im\_w>$w) { 017$new\_w=$w; 018$new\_h=$w/$im\_w\*$im\_h; 019}else{ 020$new\_w=$im\_w; 021$new\_h=$im\_h; 022} 023$dst\_im= imagecreatetruecolor($new\_w,$new\_h); 024imagecopyresampled($dst\_im,$im, 0, 0, 0, 0,$new\_w,$new\_h,$im\_w,$im\_h); 025header('Content-type:image/jpeg'); 026imagepng($dst\_im); 027imagedestroy($dst\_im); 028imagedestroy($im); 029} 030 031/\*\* 032\* 以最大高度缩放图像 033\* 034\* @param string $im 图像元数据 035\* @param float $w 最大高度 036\*/ 037staticfunctionmaxHeight($im,$h) { 038if(empty($im) ||empty($h) || !is\_numeric($h)) { 039thrownewException("缺少必须的参数"); 040} 041$im= imagecreatefromstring($im);// 创建图像 042list ($im\_w,$im\_h) \= self::getsize($im);// 获取图像宽高 043if($im\_h>$h) { 044$new\_w=$h/$im\_h\*$im\_w; 045$new\_h=$h; 046}else{ 047$new\_w=$im\_w; 048$new\_h=$im\_h; 049} 050$dst\_im= imagecreatetruecolor($new\_w,$new\_h); 051imagecopyresampled($dst\_im,$im, 0, 0, 0, 0,$new\_w,$new\_h,$im\_w,$im\_h); 052header('Content-type:image/jpeg'); 053imagepng($dst\_im); 054imagedestroy($dst\_im); 055imagedestroy($im); 056} 057 058/\*\* 059\* 生成固定大小的图像并按比例缩放 060\* 061\* @param string $im 图像元数据 062\* @param float $w 最大宽度 063\* @param float $h 最大高度 064\*/ 065staticfunctionfixed($im,$w,$h) { 066if(empty($im) ||empty($w) ||empty($h) || !is\_numeric($w) || !is\_numeric($h)) { 067thrownewException("缺少必须的参数"); 068} 069$im= imagecreatefromstring($im);// 创建图像 070list ($im\_w,$im\_h) \= self::getsize($im);// 获取图像宽高 071if($im\_w>$im\_h||$w<$h) { 072$new\_h=intval(($w/$im\_w) \*$im\_h); 073$new\_w=$w; 074}else{ 075$new\_h=$h; 076$new\_w=intval(($h/$im\_h) \*$im\_w); 077} 078//echo "$im\_w x $im\_h $new\_w x $new\_h $x $y";exit; 079// 开始创建缩放后的图像 080$dst\_im= imagecreatetruecolor($new\_w,$new\_h); 081imagecopyresampled($dst\_im,$im, 0, 0, 0, 0,$new\_w,$new\_h,$im\_w,$im\_h); 082header('Content-type:image/jpeg'); 083imagepng($dst\_im); 084imagedestroy($dst\_im); 085imagedestroy($im); 086} 087 088/\* 089\* 获取图像大小 090\* 091\* @param string $im 图像元数据 092\* @return array 093\*/ 094protectedstaticfunctiongetsize($im) { 095returnarray( 096imagesx($im), 097imagesy($im) 098); 099} 100} 101?> **index.html HTML表单文件** 01 html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 02 03 04 charset=utf-8"/> 05Mongo Gridfs 06 07 08 09 10 11 查看图片 12 13 14