`

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

 
阅读更多

用下面用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

    1.3关键词:矩阵键盘,单片机,数码管显示,汇编语言 1.4设计目的 通过本次课程设计,运用《单片机微型计算机原理及应用》所学到的知识及查询相关资料 ,完成简易计算器的设计,进一步提高单片机的系统设计和开发...

    单片机课程设计——计算器设计(1).doc

    1.3关键词:矩阵键盘,单片机,数码管显示,汇编语言 1.4设计目的 通过本次课程设计,运用《单片机微型计算机原理及应用》所学到的知识及查询相关资料 ,完成简易计算器的设计,进一步提高单片机的系统设计和开发...

    数据库课程设计——图书管理系统.doc

    数据库系统原理课程设计 课题名称:图书信息管理系统 姓 名: 班 级: 学 号: 指导老师: 2014年 01月 02日 目录 1.绪论 3 1。1 背景介绍 3 1.2 开发背景的选用及介绍 3 2.需求分析 4 2.1 系统分析 4 2。2 系统目标...

    广工操作系统的课程设计——多级文件系统(java实现,内含源码,可执行文件、核心课设报告以及相关的说明文档)

    广工操作系统课程设计——多级文件系统(java实现,内含源码,可执行文件、核心课设报告以及相关的说明文档) 主要内容: 本课程设计要求设计一个模拟的多用户多级目录的文件系统。通过具体的文件存储空间的管理、...

    Java课程设计——高校科研管理信息系统的设计与开发

    2) 科研常规管理模块:该部分集合了本系统的主要功能,实现了对全校所有科研信息的存储和管理,主要完成对相关信息的维护、查询、统计、报表、打印等。主要有科技论文管理、科技项目管理、科技著作管理、科研人员管理...

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

    例如,你可以设计一个学生成绩管理系统、一个简单的文本编辑器或一个游戏等。确保所选主题既具有挑战性又能够展示你的C语言编程技能。 进行问题分析:一旦确定了项目主题,你需要对问题进行深入分析。这包括确定问题...

    C++课程设计实验报告——学生管理系统

    中学生成绩管理信息系统设计与开发 1. 学生成绩管理系统中不同使用单位(用户)的学生人数事先无法确定. 2. 该学生成绩管理系统要求有学生成绩录入,查询,修改,删除,保存文件. 3. 系统使用文字菜单,用户通过...

    毕业设计——示波器(项目实例)

    毕业设计——示波器(项目实例) 示波器项目包含程控放大与数据,采集存储,电路电源,电路数据处理与控制,电路液晶与按键1等模块,含原程序和电路图

    课程设计——图书馆管理系统

    图书馆图书基本信息管理软件设计:采用结构体数组或文件形式存储每本书的信息,每本书应包含如下几方面的信息:主编、出版社、出版年、版次、ISBN书号、书名、定价、拥有本数、借出本数、现余本数。软件由主函数(含...

    活动冲突检测系统——C++版——源码+课程实验报告+思路分析

    编写一个程序完成活动冲突检测系统,能够录入、修改、删除活动信息,通过对活动时间的检测,提醒活动之间安排的冲突。 功能要求及说明: 1) 活动的信息包括:开始...6) 要求模块化设计,冲突检测模块要求具有复用性。

    计算机等级考试管理系统的设计与实现

    3 系统设计 3.1 系统总体结构 3.2 数据结构设计 3.2.1 数据概念结构设计——E-R模型 3.2.2 数据逻辑结构设计——关系模型 3.2.3 数据表 3.3 系统开发与运行环境确定 3.3.1 开发环境 3.3.2 运行环境 3.3.3 ...

    仓库管理系统——《课程设计》.doc

    仓库管理系统设计分析…………………………………………………………3 2.1需求分析…………………………………………………………………………………………………3 2.2模块划分………………………………………………...

    [计算机毕设]基于jsp的项目报告格式化系统设计与实现-后台模块系统设计与实现(源代码+项目报告).zip

    论文格式化系统 ——后台模块的设计与实现 论文的格式修改是一件很麻烦的...本系统设计过程中使用了当前比较流行的技术,比如使用AJAX技术来进行注册验证,系统架构使用B/S模式进行设计。 格式化;移植性;数据库

    Python——图片筛选存储模块

    图片分类的好帮手,可以创建筛选列表,将包含相应筛选条件的图片存入指定的文件夹中,筛选条件为图片名中存在的字符、汉字,上传的资源中含有文档可自己查看具体使用。

    计算机专业毕设ASP.NET在线英语自学系统——课程及自测管理的设计(源代码+论文).rar

    **计算机专业毕设:ASP.NET在线英语自学系统——课程及自测管理的设计** 本资源提供了一个基于ASP.NET技术的在线英语自学系统的设计与实现方案。该系统旨在帮助用户通过网络平台进行英语课程的学习和自我测试,从而...

    数据库课程设计——工资管理系统--职工考勤管理系统(java+sql-sever-2000).doc

    系统详细设计………………………………………9 3.1数据库逻辑设计…………………………………9 3.2各模块功能……………………………………10 3.2.1职工信息管理系统…………………………10 3.2.2职工工资管理系统...

    JSP论文格式化系统-后台模块的设计与实现(源代码+论文).rar

    它不仅为读者提供了系统设计的背景知识,还详细阐述了系统架构、模块划分、关键技术的应用以及系统测试等方面的信息。这个资料包对于计算机专业的学生、研究人员或是希望深入了解JSP应用开发的软件工程师来说,是一...

    数据库设计报告——工资管理系统.doc

    系统功能模块: 2.功能分析: 员工管理系统需要对员工的工资、奖金进行管理,还应包括员工的一些基本信息和考 勤情况、加班津贴。因此系统要满足员工工资、奖金的计算工能,通过设定的每月基本 工资和奖金,结合...

    酒店管理系统DOC 测试计划 需求分析 概要设计 详细设计

    编写本说明书的目的是说明对程序系统的设计考虑,包括程序系统的基本处理流程、程序系统的组织结构、功能分配、模块化粉、接口设计、运行设计、数据结构设计和出错设计等,比概要设计更为详细,为编码的实现打下基础...

    物联网竞赛NB-IoT开发——计数器系统(Flash存储)

    3、计数器系统开发 使用一个 NB-IoT 模块,在提供的未完成工程上进行功能开发。 任务要求:  通电后 LED2 灭,液晶屏显示如下信息(N 为自然数)。 计数器 数值:N 结果:Y  当按下 Key2 时当前数值为 N-1。 ...

Global site tag (gtag.js) - Google Analytics