文档章节

PHP操作MongoDB GridFS 存储文件,如图片文件

 蜗牛奔跑
发布于 2015/09/16 09:39
字数 1487
阅读 76
收藏 0

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

01

<?php

02

// 初始化gridfs

03

$conn = new Mongo(); // 连接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为索引取得文件

24

header('Content-type: image/png'); // 输出图片头

25

echo $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 = new Mongo(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'=>new MongoId($id)));

7

header('Content-type: image/png');

8

echo $object->getBytes();

 

 

 

 

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

gfs.php文件

01

<?php

02

// 连接Mongo并初始化GFS

03

$conn = new Mongo(C('127.0.0.1:27017')); //如果设置了密码自己配置DSN

04

$db=$conn->selectDB('edu_sns');  // 选择数据库

05

$collection = $db->getGridFS('zk_attach'); // 选择集合,相等于选择数据表

06

 

07

// 上传图片

08

if (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'));

14

    if (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 {

26

        unlink($_FILES['upfile']['tmp_name']);

27

    }

28

    echo "<p>图片路径为: <font color=red>http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}?img={$md5}</font></p>";

29

 

30

} elseif ($id = $_GET['img']) { // 生成图片

31

 

32

    // 索引图片文件

33

    $image = $collection->findOne(array('md5' => $id));

34

 

35

    // 设定文档类型,显示图片

36

    $img_bytes = $image->getBytes();

37

    include_once 'thumb.php';

38

    $w = is_numeric($_GET['w']) ? intval($_GET['w']) : 100;

39

    Thumb::maxWidth($img_bytes, $w);

40

 

41

} elseif ($id = $_GET['del']) { // 删除图片

42

    $s = $collection->remove(array('md5' => $id));

43

    header('Location:' . $_SERVER['HTTP_REFERER']);

44

 

45

} else { // 图片列表

46

    $cursor = $collection->find();

47

    foreach ($cursor as $obj) :

48

        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>';

49

    endforeach

50

    ;

51

}

52

?>

 

thumb.php 缩略图文件

001

<?php

002

class Thumb {

003

 

004

    /**

005

     * 以最大宽度缩放图像

006

     *

007

     * @param string $im 图像元数据

008

     * @param float $w 最大宽度

009

     */

010

    static function maxWidth($im, $w) {

011

        if (empty($im) || empty($w) || !is_numeric($w)) {

012

            throw new Exception("缺少必须的参数");

013

        }

014

        $im = imagecreatefromstring($im); // 创建图像

015

        list ($im_w, $im_h) = self::getsize($im); // 获取图像宽高

016

        if ($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);

024

        imagecopyresampled($dst_im, $im, 0, 0, 0, 0, $new_w, $new_h, $im_w, $im_h);

025

        header('Content-type:image/jpeg');

026

        imagepng($dst_im);

027

        imagedestroy($dst_im);

028

        imagedestroy($im);

029

    }

030

 

031

    /**

032

     * 以最大高度缩放图像

033

     *

034

     * @param string $im 图像元数据

035

     * @param float $w 最大高度

036

     */

037

    static function maxHeight($im, $h) {

038

        if (empty($im) || empty($h) || !is_numeric($h)) {

039

            throw new Exception("缺少必须的参数");

040

        }

041

        $im = imagecreatefromstring($im); // 创建图像

042

        list ($im_w, $im_h) = self::getsize($im); // 获取图像宽高

043

        if ($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);

051

        imagecopyresampled($dst_im, $im, 0, 0, 0, 0, $new_w, $new_h, $im_w, $im_h);

052

        header('Content-type:image/jpeg');

053

        imagepng($dst_im);

054

        imagedestroy($dst_im);

055

        imagedestroy($im);

056

    }

057

 

058

    /**

059

     * 生成固定大小的图像并按比例缩放

060

     *

061

     * @param string $im 图像元数据

062

     * @param float $w 最大宽度

063

     * @param float $h 最大高度

064

     */

065

    static function fixed($im, $w, $h) {

066

        if (empty($im) || empty($w) || empty($h) || !is_numeric($w) || !is_numeric($h)) {

067

            throw new Exception("缺少必须的参数");

068

        }

069

        $im = imagecreatefromstring($im); // 创建图像

070

        list ($im_w, $im_h) = self::getsize($im); // 获取图像宽高

071

        if ($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 <br/> $new_w x $new_h <br/> $x $y";exit;

079

        // 开始创建缩放后的图像

080

        $dst_im = imagecreatetruecolor($new_w, $new_h);

081

        imagecopyresampled($dst_im, $im, 0, 0, 0, 0, $new_w, $new_h, $im_w, $im_h);

082

        header('Content-type:image/jpeg');

083

        imagepng($dst_im);

084

        imagedestroy($dst_im);

085

        imagedestroy($im);

086

    }

087

 

088

    /*

089

     * 获取图像大小

090

     *

091

     * @param string $im 图像元数据

092

     * @return array

093

     */

094

    protected static function getsize($im) {

095

        return array(

096

                imagesx($im),

097

                imagesy($im)

098

        );

099

    }

100

}

101

?>

 

index.html HTML表单文件

01

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

02

<html xmlns="http://www.w3.org/1999/xhtml">

03

<head>

04

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

05

<title>Mongo Gridfs</title>

06

</head>

07

 

08

<body>

09

<form action="gfs.php" method="post" enctype="multipart/form-data">

10

    <input type="file" name="upfile"  />

11

    <input type="submit" value="upload" /> <a href="gfs.php">查看图片</a>

12

</form>

13

</body>

14

</html>

 

 

 


本文转载自:

共有 人打赏支持
粉丝 38
博文 614
码字总数 117758
作品 0
海淀
私信 提问
基于GridFS+NGinx构建分布式文件系统 之实战(三)

基于GridFS构建分布式文件系统 首先看看什么是GridFS: GridFS is a mechanism for storing large binary files in MongoDB. There are several reasons why you might consider using GridF......

一枚Sir
2014/06/20
0
1
浅尝辄止MongoDB:GridFS

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzy0623/article/details/82894835 一、为什么使用GridFS GridFS是MongoDB的一个子模块,使用GridFS可以基于M...

wzy0623
2018/09/29
0
0
MongoDB进阶系列(13)——GridFS大文件的添加、获取、查看、删除

GridFS是一种在MongoDB中存储大二进制文件的机制,使用GridFS的原因有以下几种: 存储巨大的文件,比如视频、高清图片等。 利用GridFS可以简化需求。 GridFS会直接利用已经建立的复制或分片机...

HappyBKs
2015/03/17
0
0
mongoDB--GridFS简介

前言 :GridFS从名字来看,就明白是一个文件系统,它是mongodb的一个子模块,使用GridFS可以基于mongodb来持久存储文件.并且支持分布式应用(文件分布存储和读取). 使用场景:如果你的系统有如下情...

索隆
2013/04/15
0
1
MongoDB系列教程(八):GridFS存储详解

MongoDB系列教程(八):GridFS存储详解 GridFS简介 mongoDB的文档以BSON格式存储,支持二进制的数据类型,当我们把二进制格式的数据直接保存到mongoDB的文档中。但是当文件太大时,例如图片...

开元中国2015
2015/07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

多命令链命令参数

Commands: --install <link> <name> <path> <priority> [--slave <link> <name> <path>] ... 在系统中加入一组替换项. --remove <name> <path> 从 <名......

Pulsar-V
42分钟前
1
0
【转】go get命令使用socket代理

由于某些不可描述的原因,国内使用go get命令安装某些包的时候会超时导致失败,比如net包、sys包、tools包等。第一种解决办法就是自己从git上下载后添加链接到GOPATH中,比如: 1234...

yiduwangkai
43分钟前
5
0
Windows同步对象Event和Linux的条件变量

最近在看一些同步对象模拟的东东,特别对在Windows下如何模拟条件变量折腾了很久。 1 Windows同步对象Event 微软有一个很有意思的同步对象,某种程度上和Linux的条件变量很相似。但秉承微软一...

shzwork
51分钟前
1
0
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

//第一种做法 public class Solution { public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { ArrayList <Integer> li=new ArrayList<Integer>(); ArrayList <TreeN......

南桥北木
今天
2
0
linux 服务管理 Crontba、Ntpdate、Logrotate、Supervisor

crond linux 系统则是由 cron (crond) 这个系统服务来控制的。Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的。 另外, 由于使用者自己也可以设置计划任务,所以,...

狼王黄师傅
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部