初学thinkphp,看到可以做文件上传就试着写了一下,用的mamp集成环境,thinkphp为3.2.3版本。 github地址:https://github.com/fanhu371328/fileUpload 一、先看一下项目的文件目录结构
1、index.php为项目的入口文件:
<?php // 检测PHP环境 if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !'); // 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false define('APP_DEBUG',True); // 定义应用目录 define('APP_PATH','./fanhu/'); // 引入ThinkPHP入口文件 require './ThinkPHP/ThinkPHP.php'; // 亲^_^ 后面不需要任何代码了 就是如此简单这里定义了项目的文件目录在fanhu这个文件夹下面。 2、IndexController.class.php是index控制器,代码如下:
<?php namespace Home\Controller; use Think\Controller; use Think\Upload; class IndexController extends Controller { //文件上传 public function upload(){ //实例化上传类 $upload = new Upload(); //设置上传文件大小 $upload->maxSize = 3145728; $upload->exts = array('pdf','doc','txt','xlsx'); $upload->savePath = './'; //上传路径在项目的根目录下的uploads文件夹 //上传成功后返回的信息 $info = $upload->upload(); if( !$info ){ $this->error($upload->getError()); } else { $this->success("上传成功"); } } }3、view 下的file.html为对应的模板文件,也就是页面视图部分,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>上传资料</title> <link rel="stylesheet" href="__PUBLIC__/css/public.css"> <link rel="stylesheet" href="__PUBLIC__/css/file_upload.css"> </head> <body> <div class="section"> <form id="uploadForm" class="section-top" method="post" action="./upload" enctype="multipart/form-data"> <p class="file-header">上传资料</p> <div class="upload-file"> <input type="file" name="upload[]" id="upload" /> <p> <img src="__PUBLIC__/img/wodeshangchuan.png" /> 上传我的资料 </p> <p> 每成功上传一份资料,可获得 <span>5</span> 积分奖励 </p> </div> <div class="file-content hidden"> <p>您选择的文件</p> <ul class="file-list"> <!--文件预览--> </ul> <div class="clearfix"> <p> 选择<span class="file-num">5</span>个文件,共<span class="file-size">4M</span> </p> <p> <img src="__PUBLIC__/img/PDF.png" />继续添加 </p> <input type="file" name="upload[]" class="add-more" /> </div> <input type="submit" name="submit" id="submit" value="开始上传" /> </div> </form> <!--上传资料提示信息--> <div class="section-bottom"> <div> <p class="tips-file"><img src="__PUBLIC__/img/zhuyi.png" />上传资料说明</p> <ul> <li>1、上传的资料需通过审核后才会发布</li> <li>2、支持5M以内的资料文件上传</li> <li>3、请勿在未经授权的情况下上传任何版权侵权的文档,除非文档完全由您个人创作或您得到了版权所有者的授权</li> <li>4、为了文档能正常显示,我们支持以下格式的文档上传</li> </ul> </div> <div> <p class="tips-file"><img src="__PUBLIC__/img/zhuyi.png" />支持文件格式</p> <ul> <li> <span>Microsoft office</span> <span><img src="__PUBLIC__/img/word.png"/>doc,docx</span> <span><img src="__PUBLIC__/img/ppt.png"/>ppt,pptx</span> <span><img src="__PUBLIC__/img/Excel.png"/>xls,xlsx</span> </li> <li> <span>文本</span> <span><img src="__PUBLIC__/img/TXT.png"/>txt</span> </li> <li> <span>Adobe PDF</span> <span><img src="__PUBLIC__/img/PDF.png"/>pdf</span> </li> </ul> </div> </div> </div> </body> <script src="__PUBLIC__/js/jquery-2.1.4.min.js"></script> <script src="__PUBLIC__/js/file_upload.js"></script> </html>二、文件上传方式1—>使用form表单进行提交
;(function($) { var files_content = []; //所有文件信息存储在这里,做文件预览用 var files_list = []; //所有file类型的input存储在这里,最后上传 var files_num = 1; //点击上传时的input个数 var size_all = "0Kb"; //文件总大小 var upload = document.querySelector('#upload'); var index = $('.file-content>div input').length; var addMore = document.querySelectorAll('.add-more')[index-1]; var typeArr = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'pdf', 'txt', 'text']; //所有支持的文件格式 var __PUBLIC__ = "/fileUpload/Public/"; //添加文件 upload.onchange = function() { if(upload.files.length > 0) { var fileList = upload.files; var num = 0; //添加文件和继续添加的共用方法 addFile(fileList,num); } $('.upload-file').addClass('hidden'); $('.file-content').removeClass('hidden'); //创建预览 createPreview(); allSize(); } //创建预览 function createPreview() { if(files_content.length == 0) { $('.upload-file').removeClass('hidden'); $('.file-content').addClass('hidden'); } else { var html = []; for(var i = 0; i < files_content.length; i++) { var item = files_content[i]; html.push(renderItem(item)); } $(".file-list").html(html.join('')); //文件总大小 var num = 0; for(var i = 0; i < files_content.length; i++) { num = num + (files_content[i].size) / 1024; //现在是kb } if(num >= 1024) { size_all = (num / 1024).toFixed(2) + "M"; } else { size_all = num.toFixed(2) + "Kb"; } } delate(); } function renderItem(data) { //文件名 var name = data.name; var size = data.size; //文件类型 var type = name.split('.')[1].toLowerCase(); var src = __PUBLIC__ + "img/PDF.png"; switch(type) { case "doc": src = __PUBLIC__ + "img/word.png"; break; case "docx": src = __PUBLIC__ + "img/word.png"; break; case "ppt": src = __PUBLIC__ + "img/ppt.png"; break; case "pptx": src = __PUBLIC__ + "img/ppt.png"; break; case "xls": src = __PUBLIC__ + "img/Excel.png"; break; case "xlsx": src = __PUBLIC__ + "img/Excel.png"; break; case "txt": src = __PUBLIC__ + "img/TXT.png"; break; case "pdf": src = __PUBLIC__ + "img/PDF.png"; break; } //文件大小 size = (size / 1024).toFixed(2) + "Kb"; //最终要展示的单个文件大小 if(parseFloat(size) >= 1024) { size = (parseInt(size) / 1024).toFixed(2) + "M"; } var str = '<li class="clearfix">\ <p>\ <img class="type-icon" src="' + src + '" />\ <span>' + data.name + '</span>\ </p>\ <div class="progress-content hidden">\ <progress></progress>\ <span id="progress">0%</span>\ </div>\ <span class="size">' + size + '</span>\ <img class="close-icon" name="close" src="' + __PUBLIC__ + 'img/guanguanbi.png" />\ </li>'; return str; } //计算文件总数和总大小 function allSize() { //文件数 var length = files_content.length; $('.file-num').html(length); //文件总大小 $('.file-size').html(size_all); } //删除文件 function delate() { $('.file-list li').on('click', function(e) { if(e.target.name == 'close') { var index = $(this).index(); //删除对应的input节点,并将input数量减1 $('.section-top input[type="file"]').eq(index).remove(); files_num--; //重新赋值全部文件数组 var arr = []; for(var i = 0; i < files_content.length; i++) { if(i != index) { arr.push(files_content[i]) } } files_content = arr; //文件总大小 var num = 0; for(var i = 0; i < files_content.length; i++) { num = num + (files_content[i].size) / 1024; //现在是kb } if(num >= 1024) { size_all = (num / 1024).toFixed(2) + "M"; } else { size_all = num.toFixed(2) + "Kb"; } allSize(); //重新加载预览视图 createPreview(); } }) $('.close-icon').on('mouseover', function() { $(this).addClass('close-icon1'); }) $('.close-icon').on('mouseout', function() { $(this).removeClass('close-icon1'); }) } //继续添加文件 addMore.onchange = function() { if(addMore.files.length > 0) { var fileList = addMore.files; var num = 0; addFile(fileList,num); //添加文件完成后再创建一个input,置于现有的input之上 $('.file-content>div input').addClass('hidden'); cereateInput(); } //创建预览 createPreview(); allSize(); } function addFile(fileList,num) { for(var item in fileList) { //数组后面会自动添加两项不是我们需要的,排除出去 if(num < fileList.length) { //对格式和大小进行判断 var type = fileList[item].name; var flag = false; for(var i = 0; i < typeArr.length; i++) { if(type.indexOf(typeArr[i]) >= 0) { flag = true; //能够匹配到一种格式就置为true } } if(flag == true) { //格式符合的再判断大小,都符合条件再添加到文件集合中 if(fileList[item].size / 1024 > 5120) { alert("上传的文件" + fileList[item].name + "大小超过了5M!") } else { files_content.push(fileList[item]); } } else { alert("上传的文件" + fileList[item].name + "格式不支持!") } } num++; } } //添加一个文件就创建一个file类型的input,只是不显示,用来存储文件 function cereateInput(){ $('.file-content>div').append('<input type="file" name="upload[]" style="z-index:'+ files_num +'" class="add-more"/>'); var addMore = document.querySelectorAll('.add-more')[files_num]; //继续添加文件 addMore.onchange = function(){ if(addMore.files.length > 0){ var fileList = addMore.files; var num = 0; addFile(fileList,num); //添加文件完成后再创建一个input,置于现有的input之上 $('.file-content>div input').addClass('hidden'); files_num++; console.log(files_num) cereateInput(); } //创建预览 createPreview(); allSize(); } } })(jQuery)三、使用ajax方式进行提交 如果使用ajax提交就把form的action去掉,把input—>type=submit改为type=button,通过添加点击事件来触发, 在原有的js代码基础上增加一下代码: 注意:contentType: false和processData: false 是必须要加上的,通过使用ajax提交文件可以检测到文件的上传进度,下面的代码中就是添加了一个进度条的例子。 需要在页面中增加进度条的部分:
<div class="progress-content hidden"> <progress></progress> <span id="progress">0%</span> </div> //上传 $('#submit').on('click', function() { //点上传时显示进度条 $('.progress-content').removeClass('hidden'); var formData = new FormData($("#uploadForm")[0]); uploadFile(formData); }) function uploadFile(Data){ $.ajax({ url : "./upload", type: "POST", data: Data, xhr : function(){ //获取ajaxSettings中的xhr对象,为它的upload属性绑定progress事件的处理函数 myXhr = $.ajaxSettings.xhr(); if(myXhr.upload){ //检查upload属性是否存在 //绑定progress事件的回调函数 myXhr.upload.addEventListener('progress',progressHandlingFunction, false); } return myXhr; //xhr对象返回给jQuery使用 }, success: function(result){ console.log(result); }, contentType: false, //必须false才会自动加上正确的Content-Type processData: false //必须false才会避开jQuery对 formdata 的默认处理 }); } //上传进度回调函数: function progressHandlingFunction(e) { if (e.lengthComputable) { $('progress').attr({value : e.loaded, max : e.total}); //更新数据到进度条 var percent = e.loaded/e.total*100; $('#progress').html(percent.toFixed(2) + "%"); } }页面效果如下:支持的文件格式和单个文件大小是可以设置的
可以继续添加文件或者删除文件
点击上传之后会显示进度条
文件上传完成后进入开始的 uploads文件目录下就可以看到刚才上传的文件了。