`

模块简单设计——设计简单的存储系统

 
阅读更多

用下面用nginx+mongodb+php实现一个简单的存储系统,提供简单的文件上传下载功能(下载支持Range头)。

(后台用磁盘和mongo的gridfs分别存储大于1M和小于等于1M的文件)

 

A,前台文件上传页面(同时列举所有文件)(test.php)

<html>
<head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<body>
	<!--查询meta中所有文件-->
        <ul>
                <?php

                        $mongo = new Mongo();
                        $db = $mongo->selectDB("ciaos");
                        $meta = $db->meta;
                        $cursor = $meta->find();

                        foreach ($cursor as $doc) {
                                $filename = $doc["filename"];
                                echo "<li><a href=\"dl/$filename\">$filename</a></li>";
                        }

                ?>
        </ul>

        <form enctype="multipart/form-data" action="upload.php" method="POST">
        <!-- Name of input element determines name in $_FILES array -->
                Send this file: <input name="Filedata" id="Filedata" type="file" />
                <input name="submit" type="submit" value="Send File" />
        </form>

</body>
</html>

B,服务器端文件上传(upload.php)

<?php

// 存放文件的磁盘位置
$targetFolder = '/files';

if (!empty($_FILES)) {

        //获取上传文件的临时文件,大小,设置存储路径
        $tempFile = $_FILES['Filedata']['tmp_name'];
        $size = $_FILES['Filedata']['size'];
        $targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
        $targetFile = rtrim($targetPath,'/') . '/' . $_FILES['Filedata']['name'];

        $mongo = new Mongo();
        $db = $mongo->selectDB("ciaos");

        //大于1M的文件放在磁盘中,然后写meta信息
        if($size > 1024*1024) {
                move_uploaded_file($tempFile,$targetFile);

                $newfile = array(
                                "filename" => $_FILES['Filedata']['name'],
                                "savename" => $targetFile,
                                "size" => $size
                        );
        } else { //小文件存放在mongofs中,然后写meta
                $gridfs = $db->getGridFS();
                $mid = $gridfs->put($tempFile);

                $newfile = array(
                                "filename" => $_FILES['Filedata']['name'],
                                "mid" => $mid,
                                "size" => $size
                        );
        }

        //meta中存储文件名信息,mongoID或者存储名称以及文件大小
        $meta = $db->meta;
        $meta->save($newfile);

        echo "Upload succeed";

}
else {
        echo "Upload failed";
}

exit();
?>

C,文件下载逻辑(download.php)

<?php

$file = isset($_GET["file"])?$_GET["file"]:NULL;

if ($file) {

        //去meta中查询文件信息
        $mongo = new Mongo();
        $db = $mongo->selectDB("ciaos");
        $meta = $db->meta;

        $search = array(
                "filename"=>$file
        );
        $search_result = $meta->findOne($search);
        $size=  $search_result["size"];

        //如果文件大于1M,转到磁盘下载
        if($size > 1024*1024) {
                header("Content-type: application/octet-stream");
                header("X-Accel-Redirect: /files/" . $file);
        } else { //小文件则从mongofs中读取存放在临时文件中,然后转临时文件下载
                $gridfs = $db->getGridFS();

                $mid = $search_result["mid"];
                $fsfile = $gridfs->get($mid);
                $tmpname = "tmp".time();
                file_put_contents("./files/$tmpname",$fsfile->getBytes());

                header("Content-type: application/octet-stream");
                header("X-Accel-Redirect: /files/" . $tmpname);
        }
}
else {
        echo "Invalid filename";
}

?>

如果下载文件名为download.php,可以加上这样一个头指定文件名header("Content-Disposition: attachment; filename= $filename");

daemon启动方法:bin/mongod --fork --logpath /data/db/mongodb.log(需要有/data/db/目录用于存放数据)

D,数据库中存储小文件内容以及meta信息,查询结果分别如下

> db.fs.files.find()
{ "_id" : ObjectId("50b5d1a892a5f27a0f000001"), "filename" : "/usr/local/NSP/var/php_upload_tmp/phpmgM6IS", "uploadDate" : ISODate("2012-11-28T08:56:08.480Z"), "length" : 13, "chunkSize" : 262144, "md5" : "d4369b7a8614277c011ef987ca4e16ee" }
{ "_id" : ObjectId("50b5ddb592a5f2452f000001"), "filename" : "/usr/local/NSP/var/php_upload_tmp/php4hu6fi", "uploadDate" : ISODate("2012-11-28T09:47:33.094Z"), "length" : 13, "chunkSize" : 262144, "md5" : "d4369b7a8614277c011ef987ca4e16ee" }
>
> db.meta.find()
{ "_id" : ObjectId("50b5d8ca92a5f2b42d000000"), "filename" : "dbank-sdk-cpp-0.5.5.zip", "savename" : "/usr/local/NSP/htdocs/files/dbank-sdk-cpp-0.5.5.zip", "size" : 4380805 }
{ "_id" : ObjectId("50b5ddb592a5f2452f000003"), "filename" : "测试.txt", "mid" : ObjectId("50b5ddb592a5f2452f000001"), "size" : 13 }
>

E,nginx核心配置(nginx.conf)

location / {
		index  index.html index.htm index.php;
		rewrite ^/dl/(.*) /download.php?file=$1 last;
}

location /files {
		root /usr/local/ciaos/html/;
		internal;
}

location ~ .*\.php$ {
		fastcgi_index index.php;
		fastcgi_pass   unix:/usr/local/ciaos/php_fcgi.socket;
		include /usr/local/ciaos/fastcgi.conf;
}

nginx的配置主要需要注意下面几点:

1,支持php服务器端脚本运行

2,配置下载目录/files,设置为internal内部访问,这样可以避免用户直接下载磁盘,可以自定义鉴权等功能

3,配置路径转发,前台的下载路径看起来就是这样http://localhost/dl/test.txt,后台通过download.php实现下载功能。

分享到:
评论

相关推荐

    软件工程课程设计——餐厅点餐系统.doc

    2. 系统设计需要考虑到系统的可扩展性、可维护性和可靠性。 3. 数据库设计需要考虑到数据的存储和查询效率。 4. 编程语言的选择需要考虑到系统的性能和可靠性。 5. 软件测试需要考虑到系统的稳定性和可靠性。 软件...

    软件工程课程设计——教务管理系统

    1. 软件工程课程设计:本系统设计是一个典型的软件工程课程设计项目,涵盖了需求分析、系统设计、数据流图、系统模块层次图、数据库设计等多个方面。 2. 教务管理系统:本系统的设计目标是一个教务管理系统,旨在...

    基于单片机的智能家居控制系统——传感器信号采集、GSM模块和红外学习遥控设计与分析.pdf

    根据提供的文件信息,本文将从以下几个方面详细说明关于基于单片机的智能家居控制系统的设计与分析的知识点: ...这些知识对于从事智能家居系统设计与分析的专业人士来说,是必须具备的基本技能。

    ASP.NET毕业设计——asp.net数据存储与交换系统设计(源代码+论文).zip

    这个毕业设计项目——“ASP.NET数据存储与交换系统设计”展示了如何利用ASP.NET技术来开发一个能够存储和交换数据的系统。该系统可能涉及到数据库管理、数据传输以及用户交互等多个关键模块。 在项目中,"H...

    Freescale 系列单片机常用模块与综合系统设计——光盘

    在本文中,我们将深入探讨Freescale系列单片机的常用模块及其综合系统设计。Freescale(现为NXP半导体的一部分)是全球知名的微控制器制造商,其产品广泛应用于各种嵌入式系统中。Freescale系列单片机以其高性能、低...

    石油大学软件工程课程设计——毕业设计管理系统

    需求分析是系统设计的关键步骤,它包括了解用户需求、定义系统功能和非功能需求。毕业设计管理系统的核心功能可能包括:学生提交毕业设计计划、教师审批、进度报告提交、成绩录入、文档管理、在线交流等。非功能需求...

    C语言课程设计——学生考勤管理系统.doc

    【C语言课程设计——学生考勤管理系统】 在本次C语言课程设计中,学生将构建一个学生考勤管理系统,旨在管理并统计学生的缺勤情况。这个系统需具备录入、修改、查询和统计等功能,并以菜单驱动的方式运行,提供友好...

    VC课程设计——通讯录管理系统

    本文将从VC课程设计——...总结起来,本文讨论了通讯录管理系统的设计和实现,包括系统设计思想、系统功能模块设计、系统实现和系统开发目标。该系统具有实用性、可靠性和适用性,能够满足用户对通讯录信息的管理需求。

    CPU设计——数据通路的设计与实现-四川大学计算机组成原理高分实验报告.doc

    《CPU设计——数据通路的设计与实现》是四川大学计算机组成原理课程的一份高分实验报告,旨在通过设计和实现CPU中的数据通路,让学生深入理解计算机内部的工作机制。实验内容涉及了CPU的核心组成部分,包括数据通路...

    UML课程设计——人事工资管理系统

    UML课程设计——人事工资管理系统 本资源摘要信息中,我们将对人事工资管理...人事工资管理系统的UML课程设计是一个复杂的系统设计过程。我们需要对系统的需求、用例设计、结构设计和部署等方面进行详细的设计和实现。

    小程序模块化开发——模块.zip

    微信小程序提供了`wx.setStorageSync`和`wx.getStorageSync`来处理简单的数据存储,对于复杂的业务逻辑,可以引入第三方状态管理库如`wepy-redux`或自建状态管理方案。 6. **模块生命周期**:每个小程序模块都有其...

    数据库课程设计——人事管理系统

    在系统设计阶段,设计者充分考虑了易用性、用户界面、系统的灵活性、实用性及安全性。在架构选择上,系统采用了常见的客户端/服务器(C/S)架构。客户端负责与用户直接交互,提供用户友好的操作界面,并负责数据库的...

    基于java-web-技术的高校教务系统的设计与实现——选课系统子模块.doc

    2.B/S结构的高校选课系统设计思想:B/S结构的高校选课系统设计思想是指基于浏览器/服务器结构的高校选课系统的设计思想。该设计思想主要是指高校选课系统的系统架构、系统功能模块、数据库设计等方面的设计思想。 3...

    基于虚拟仪器的轮胎硫化温度、压力控制系统设计——数据库部分软件设计.doc

    "基于虚拟仪器的轮胎硫化温度、压力控制系统设计——数据库部分软件设计" 该系统设计的目的是为了解决轮胎硫化过程中的温度和压力控制问题。硫化是制造轮胎的最后工序,硫化质量的好坏直接关系轮胎产品的质量和成品...

    Java程序设计——房产中介管理系统

    《Java程序设计——房产中介管理系统》是一份课程设计报告,旨在通过Java技术和Oracle数据库实现一个简易的房产中介系统。这份报告出自数学与信息工程学院信息管理与信息系统专业的学生之手,详细阐述了系统的设计...

    《数据库概论》课程设计——学生成绩管理系统.doc

    3. 系统设计 在系统的设计中,我们使用了多种技术和方法,如数据库设计、系统架构设计和用户界面设计等。数据库设计是指对数据库的设计,如数据库的 schema 设计和数据表的设计等。系统架构设计是指对系统的架构...

    毕业设计——人力资源管理系统

    3. **系统设计原则**:遵循面向对象的编程思想,采用模块化设计,保证系统的可扩展性和灵活性。 #### 三、系统实现 1. **Domain层实现**:负责定义业务实体类,封装业务规则和属性。 2. **DAO层实现**:Data ...

    C语言课程设计——图书管理系统

    在本项目中,"C语言课程设计——图书管理系统" 是一个使用C语言编写的实践项目,旨在帮助学生理解和应用单向链表数据结构。通过这个系统,用户可以进行图书的添加、删除、查找等基本操作,是学习数据结构与算法以及...

    嵌入式系统——从SoC芯片到系统(第2版) (普通高等教育十一五国 家级规划教材,微电子与集成电路设计系列规划教材) by 凌明

    《嵌入式系统——从SoC芯片到系统(第2版)》是凌明、王学香、单伟伟合著的一本高等教育“十一五...通过实际案例分析、思考题和扩展阅读,读者可以深入理解嵌入式系统设计的各个方面,并提升其在实际项目中的应用能力。

Global site tag (gtag.js) - Google Analytics