GridFS是MongoDB的一个内置功能,它提供一组文件操作的API以利用MongoDB存储文件,GridFS的基本原理是将文件保存在两个Collection中,一个保存文件索引,一个保存文件内容,文件内容按一定大小分成若干块,每一块存在一个Document中,这种方法不仅提供了文件存储,还提供了对文件相关的一些附加属性(比如MD5值,文件名等等)的存储。

<?php
// 初始化gridfs
$conn = new Mongo(); // 连接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 = new Mongo(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'=>new MongoId($id)));
header('Content-type: image/png');
echo $object->getBytes();

最近因工作需要研究了下GridFS,并整理了个Demo出来。。分享一下经验。。

gfs.php文件

<?php
// 连接Mongo并初始化GFS
$conn = new Mongo(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)) {
$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 "<p>图片路径为: <font color=red>http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}?img={$md5}</font></p>"; } 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));
header('Location:' . $_SERVER['HTTP_REFERER']); } else { // 图片列表
$cursor = $collection->find();
foreach ($cursor as $obj) :
echo '<p><a href="?img=' . $obj->file['md5'] . '&w=800"><img src="?img=' . $obj->file['md5'] . '" border="0" /></a><a href="?del=' . $obj->file['md5'] . '">删除</a></p>';
endforeach
;
}
?>

thumb.php 缩略图文件

<?php
class Thumb { /**
* 以最大宽度缩放图像
*
* @param string $im 图像元数据
* @param float $w 最大宽度
*/
static function maxWidth($im, $w) {
if (empty($im) || empty($w) || !is_numeric($w)) {
throw new Exception("缺少必须的参数");
}
$im = imagecreatefromstring($im); // 创建图像
list ($im_w, $im_h) = self::getsize($im); // 获取图像宽高
if ($im_w > $w) {
$new_w = $w;
$new_h = $w / $im_w * $im_h;
} else {
$new_w = $im_w;
$new_h = $im_h;
}
$dst_im = imagecreatetruecolor($new_w, $new_h);
imagecopyresampled($dst_im, $im, 0, 0, 0, 0, $new_w, $new_h, $im_w, $im_h);
header('Content-type:image/jpeg');
imagepng($dst_im);
imagedestroy($dst_im);
imagedestroy($im);
} /**
* 以最大高度缩放图像
*
* @param string $im 图像元数据
* @param float $w 最大高度
*/
static function maxHeight($im, $h) {
if (empty($im) || empty($h) || !is_numeric($h)) {
throw new Exception("缺少必须的参数");
}
$im = imagecreatefromstring($im); // 创建图像
list ($im_w, $im_h) = self::getsize($im); // 获取图像宽高
if ($im_h > $h) {
$new_w = $h / $im_h * $im_w;
$new_h = $h;
} else {
$new_w = $im_w;
$new_h = $im_h;
}
$dst_im = imagecreatetruecolor($new_w, $new_h);
imagecopyresampled($dst_im, $im, 0, 0, 0, 0, $new_w, $new_h, $im_w, $im_h);
header('Content-type:image/jpeg');
imagepng($dst_im);
imagedestroy($dst_im);
imagedestroy($im);
} /**
* 生成固定大小的图像并按比例缩放
*
* @param string $im 图像元数据
* @param float $w 最大宽度
* @param float $h 最大高度
*/
static function fixed($im, $w, $h) {
if (empty($im) || empty($w) || empty($h) || !is_numeric($w) || !is_numeric($h)) {
throw new Exception("缺少必须的参数");
}
$im = imagecreatefromstring($im); // 创建图像
list ($im_w, $im_h) = self::getsize($im); // 获取图像宽高
if ($im_w > $im_h || $w < $h) {
$new_h = intval(($w / $im_w) * $im_h);
$new_w = $w;
} else {
$new_h = $h;
$new_w = intval(($h / $im_h) * $im_w);
}
//echo "$im_w x $im_h <br/> $new_w x $new_h <br/> $x $y";exit;
// 开始创建缩放后的图像
$dst_im = imagecreatetruecolor($new_w, $new_h);
imagecopyresampled($dst_im, $im, 0, 0, 0, 0, $new_w, $new_h, $im_w, $im_h);
header('Content-type:image/jpeg');
imagepng($dst_im);
imagedestroy($dst_im);
imagedestroy($im);
} /*
* 获取图像大小
*
* @param string $im 图像元数据
* @return array
*/
protected static function getsize($im) {
return array(
imagesx($im),
imagesy($im)
);
}
}
?>

index.html HTML表单文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mongo Gridfs</title>
</head> <body>
<form action="gfs.php" method="post" enctype="multipart/form-data">
<input type="file" name="upfile" />
<input type="submit" value="upload" /> <a href="gfs.php">查看图片</a>
</form>
</body>
</html>

延伸阅读:

Windows下安装MongoDB

【荐】PHP操作MongoDB GridFS 存储文件,如图片文件的更多相关文章

  1. 将gridFS中的图片文件写入硬盘

    开启用户验证下的gridfs 连接使用,在执行脚本前可以在python shell中 from pymongo import Connectionfrom gridfs import *con = C ...

  2. MongoDB GridFS 存储文件

    使用MongoDB的GridFS方式. CSDN: https://blog.csdn.net/qq_32657967/article/details/81534259官方文档: https://do ...

  3. c#通过操作mongodb gridfs实现文件的数据库存储

    @(编程) 源码 using MongoDB.Driver; using MongoDB.Driver.GridFS; using System.IO; namespace Wisdombud.Mon ...

  4. MongoDB入门(8)- c#通过操作MongoDB GridFS实现文件的数据库存储

    GridFS介绍 GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件. GridFS GridFS长啥样 /* 1 */ { "_id" : ObjectId(& ...

  5. CentOS6.3搭建Nginx代理访问MongoDB GridFS图片资源

    PHP可以直接读取MongoDB GridFS中的图片并显示到页面中,但对PHP的压力就大了.偶然机会,了解到Nginx可以代理访问,实现过程如下: 1.工具准备 安装一些必要的编译工具及库,这里是直 ...

  6. MongoDB GridFS(命令行+php操作)

    一.GridFS是什么 & 为什么需要它 我们知道目前MongoDB的BSON文件最大只能是16M,也就是说单个文档最多只能存储16M的数据,那么如果需要MongoDB存储超过16M的大文件该 ...

  7. mongodb Gridfs操作

    GridFS 介绍 GridFS是MongoDB规范用于存储和检索大文件,如图片,音频文件,视频文件等.这是一种文件系统用来存储文件,但数据存储于MongoDB集合中.GridFS存储文件比其文档大小 ...

  8. MongoDB学习笔记(二)--Capped集合 && GridFS存储文件

    Capped集合                                                            Capped集合的大小是固定的,如果空间都被用完了,新添加的对象 ...

  9. Spring Boot使用MongoDB GridFS进行文件的操作

    1. GridFS简介 GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片.音频.视频等),但是它是存储在MonoDB的集合中. GridFS 会将文件对象分割成多个的ch ...

随机推荐

  1. PHP_Bibel阅读笔记(二)——脸黑的一天(?一年)

    一早上起来把50包开了,一张橙卡...就问还有谁...........本命年啊,我去买红内裤还不行么.... 实时更新,老哥的号的30包什么都没有....不过中午又开了5包,皇帝,好评啊!!! 五.代 ...

  2. 【CSS】过渡、动画和变换

    1. 使用过渡 过渡效果一般是由浏览器直接改变元素的CSS属性实现的.例如,如果使用:hover选择器,一旦用户将鼠标悬停在元素之上,浏览器就会应用跟选择器关联的属性. <!DOCTYPE ht ...

  3. python3 下的文件输入输出特性以及如何覆盖文件内容和接下去输入

    今天碰到了一个非常有意思的python特性.本来我是想打开一个文件,在文件的末尾接下去输入一些内容的,代码如下: f = open('test.txt', 'r+') f.write(content) ...

  4. 在文件夹中 的指定类型文件中 查找字符串(CodeBlocks+GCC编译,控制台程序,仅能在Windows上运行)

    说明: 程序使用 io.h 中的 _findfirst 和 _findnext 函数遍历文件夹,故而程序只能在 Windows 下使用. 程序遍历当前文件夹,对其中的文件夹执行递归遍历.同时检查遍历到 ...

  5. MySQL的基本知识 -- 函数

    MySQL基本知识 -- 进阶(常用的函数) Tags: MySQL MySQL进阶 1.计算字段 1.概念 : 如果客户端想要的数据格式不是数据库直接在表中存储的数据格式的话,有两种处理方式.第一种 ...

  6. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 基于数据库资源的多语言实现

    以前的开发平台里,是用xml语言包实现了多语言功能,现在新的平台里进行了调整,把多语言包资源放在数据库表里实现了. 我们系统预留了多语言的配置全局变量.可以通过配置这个参数达到切换多语言的目的 我们在 ...

  7. C#.NET 大型企业信息化系统集成快速开发平台 4.1 版本 - 面向数据库SQL语句的应用开发二

    很多传统企业.包括系统集成类的IT企业,若不是从事专业软件开发领域的,能做出一套适合本公司企业信息化的灵活的信息系统还是很有难度的,还有一些已经多年不写程序的资深开发人员,初学者,都难把一个整套系统实 ...

  8. jQuery的一些常用的方法(转载)

    操作元素的样式 主要包括以下几种方式: $("#msg").css("background"); //返回元素的背景颜色 $("#msg") ...

  9. 解决某些Android Permission denied

    最近遇到一个问题,总是在模拟器重报Permission denied错误,于是我直接在手机上测试,发现没有错误,于是很郁闷,反复在AndroidManifest中加入权限   <uses-per ...

  10. Android6.0动态申请权限

    先直接看代码: public void onClick(View v){ onCallPermission(); } public void onCallPermission(){ if (Build ...