GridFS是MongoDB的一个内置功能,它提供一组文件操作的API以利用MongoDB存储文件,GridFS的基本原理是将文件保存在两个Collection中,一个保存文件索引,一个保存文件内容,文件内容按一定大小分成若干块,每一块存在一个Document中,这种方法不仅提供了文件存储,还提供了对文件相关的一些附加属性(比如MD5值,文件名等等)的存储。
01
02//
初始化gridfs
03$conn=newMongo();//
连接MongoDB
04$db=$conn->photos;//
选择数据库
05$collection=$db->getGridFS();//
取得gridfs对象
06
07//
gridfs有三种方式存储文件
08//
第一种直接存储文件
09$id=$collection->storeFile("./logo.png");
10
11//
第二种存储文件二进制流
12$data=
get_file_contents("./logo.png");
13$id=$collection->storeBytes($data,array("param"=>'附加参数将随图片一起存入'));
14
15//
第三种保存直接表单提交的文件$_FILES
16$id=$collection->storeUpload('upfile');
17//
相当于
18$id=$collection->storeFile($_FILES['upfile']['tmp_name']);
19
20//--------------以上是保存图片--下面开始读取图片----------------
21
22//
保存成功后返回$id = md5字符串
23$logo=$collection->findOne(array('_id'=>$id));//
以_id为索引取得文件
24header('Content-type:
image/png');//
输出图片头
25echo$logo->getBytes();//
输出数据流
26?>
特别备注:
通过$id = $collection->storeFile($_FILES['upfile']['tmp_name']);产生的ID,是MongoDB的ID对象,而不是一个字符串!如以下格式:
1{
2"_id":
ObjectId("525418525ba8a18c1b000001"),
3"filename":"D:\\php\\xampp\\tmp\\php8116.tmp",
4"uploadDate":
ISODate("2013-10-08T14:36:02.0Z"),
5"length":
NumberInt(55862),
6"chunkSize":
NumberInt(262144),
7"md5":"a6f19f3434f0b36bb2611cd4c6d82b35"
8}
不过,我们可以通过$id = strval($id),把上述ID对象字符串化,如可得到上述的525418525ba8a18c1b000001值,再把这个值存到MySQL数据库中,到时候可通过这个 字符串ID 作为条件,找到相应的MongoDB资源。参考代码如下:
1$conn=newMongo(C('127.0.0.1:27017'));//如果设置了密码自己配置DSN
2$db=$conn->selectDB('edu_sns');//
选择数据库
3$collection=$db->getGridFS('zk_attach');//
选择集合,相等于选择数据表
4
5$id=$_GET['id'];
6$object=$collection->findOne(array('_id'=>newMongoId($id)));
7header('Content-type:
image/png');
8echo$object->getBytes();
最近因工作需要研究了下GridFS,并整理了个Demo出来。。分享一下经验。。
gfs.php文件
01
02//
连接Mongo并初始化GFS
03$conn=newMongo(C('127.0.0.1:27017'));//如果设置了密码自己配置DSN
04$db=$conn->selectDB('edu_sns');//
选择数据库
05$collection=$db->getGridFS('zk_attach');//
选择集合,相等于选择数据表
06
07//
上传图片
08if(isset($_FILES['upfile']))
{
09
10//
保存新上传的文件
11$size=$_FILES['upfile']['size'];
12$md5=
md5_file($_FILES['upfile']['tmp_name']);
13$exists=$collection->findOne(array('md5'=>$md5,'length'=>$size),array('md5'));
14if(empty($exists))
{
15$collection->storeUpload('upfile');
16
17//
或修改为如下代码,并存入一些自定义参数
18/*
19$filename=$_FILES['upfile']['name'];
20$filetype=$_FILES['upfile']['type'];
21$tmpfilepath=$_FILES['upfile']['tmp_name'];
22$id=$gridfs->storeFile($tmpfilepath,
array('filename' => $filename, 'filetype' => $filetype));
23*/
24
25}else{
26unlink($_FILES['upfile']['tmp_name']);
27}
28echo"
图片路径为:
http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}?img={$md5}";
29
30}elseif($id=$_GET['img'])
{//
生成图片
31
32//
索引图片文件
33$image=$collection->findOne(array('md5'=>$id));
34
35//
设定文档类型,显示图片
36$img_bytes=$image->getBytes();
37include_once'thumb.php';
38$w=is_numeric($_GET['w'])
?intval($_GET['w'])
: 100;
39Thumb::maxWidth($img_bytes,$w);
40
41}elseif($id=$_GET['del'])
{//
删除图片
42$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