图片上传是不少网站必备的功能之一,异步多图上传也是不少初学者比较头疼的问题。因此今天咱们就使用比较热门的Thinkphp和jquery File upload插件完整的开发一个多图异步上传功能。php
这篇文章,咱们会包含以下几个功能:css
jquery File upload上传按钮优化html
上传单图片,和多张图片上传预览前端
多张图片上传后删除,从新上传功能jquery
Thinkphp后台图片的上传、存储git
图片上传后如何在页面的显示github
其中上传多张图片会放到下一篇文章,地址写好了贴:ajax
上传图片插件咱们这里选用的是比较出名的jQuery File Upload插件,Github地址为:https://github.com/blueimp/jQ...thinkphp
Demo在这里:https://blueimp.github.io/jQu...,这里咱们选用该插件的基础功能,也就是Base版本。数据库
后台处理图片上传程序,咱们选择Thinkphp框架,也是国内很是热门的框架之一。
先看下jquery插件下载下来后的目录文件:
这一堆文件里面,咱们只须要取出js文件夹中的jquery.fileupload.js
,jquery.iframe-transport.js
,jquery.ui.widget.js
和css文件夹中的jquery.fileupload.css
便可。
在thinkphp框架的Public目录中新建css,js,img,uploads文件夹用来分别存储对应的文件。其中img文件夹须要放一张图片添加按钮图片。
uploads文件夹放置的是上传的图片目录
下面资源整合功能就大功告成了。
单张图片应用通常在文章封面图上传,或者文章中插入图片等等。好比segemntfault的这里:
首先在Thinkphp控制器文件夹新建IndexController.class.php
,而后新建一个add_img
方法用来显示上传图片界面,而且完成view等文件的创建。
/** * 添加图片上传页面 */ public function add_img() { $this->display(); }
下面首先在html页面引入相关js,css资源
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加图片</title> <link rel="stylesheet" href="__PUBLIC__/css/jquery.fileupload.css"> </head> <body> <script src="__PUBLIC__/js/jquery-2.1.4.min.js"></script> <script src="__PUBLIC__/js/jquery.ui.widget.js"></script> <script src="__PUBLIC__/js/jquery.iframe-transport.js"></script> <script src="__PUBLIC__/js/jquery.fileupload.js"></script> </body> </html>
这里要注意一下,除了须要引入必备的图片上传插件。还须要注意引入jquery
文件。
接下来就咱们就新建一个表单。
<form action="" id="submitForm"> <div class="fileinput-button"> <div class="thumbnail" id="thumbnail"> <div class="cover"> <img src="__PUBLIC__/img/add_img.png" /> </div> </div> <!-- The file input field used as target for the file upload widget --> <input id="fileupload" type="file" name="upload_img"> <div id="img_url"></div> <!-- The container for the uploaded files --> <div id="files" class="files"></div> </div> <div class="form-group"> <label for="img_name">图片名称</label> <input type="text" name="img_name" value="" id="img_name"> <button type="button" id="submit">提交表单</button> </div> </form>
解释一下:
其中fileinput-button
是十分重要的一个元素,不可缺乏
其中的.thumbnail
是一个用于放图片上传后显示缩略图的地方
其中的id="fileupload"
则是浏览器默认的上传插件
最后的一个form-group
中内元素为咱们须要提交的附加信息,好比图片名称或者其余信息
咱们使用jquery插件的还有一个缘由就是由于,浏览器默认的上传控件太丑啦。因此,优化操做必不可少。
form{ width:500px; margin:100px auto;} .form-group{ margin-top:20px;} .fileinput-button { position: relative; overflow: hidden; border:2px dashed #E5E5E5; text-align: center; } .fileinput-button .cover{ padding:50px 0;} .fileinput-button .up-img{ width:500px;;} .fileinput-button .up-img img{max-width: 100%;} .fileinput-button input { position: absolute; top: 0; right: 0; margin: 0; opacity: 0; -ms-filter: 'alpha(opacity=0)'; font-size: 200px !important; direction: ltr; cursor: pointer; } /* Fixes for IE < 8 */ @media screen\9 { .fileinput-button input { filter: alpha(opacity=0); font-size: 100%; height: 100%; } }
其中第一行,第二行的form
和.form-group
是后面的附加元素,因此不重要。
以后的每一行都是用于控件美化。最后还有用于ie
浏览器的专门优化。
下面咱们直接将官方demo中的js代码copy过来用于图片上传操做
<script> var uploadUrl = "{:U('index/upload')}"; var baseUrl = "__PUBLIC__/uploads/"; // 图片上传部分 $(function () { 'use strict'; // Change this to the location of your server-side upload handler: $('#fileupload').fileupload({ url: uploadUrl, dataType: 'json', done: function (e, data) { // 这里是图片上传完成后的代码 }, progressall: function (e, data) { // 这里处理图片正在上传的进度 } }).prop('disabled', !$.support.fileInput) .parent().addClass($.support.fileInput ? undefined : 'disabled'); }); </script>
看下最上面的两个js全局变量uploadUrl
是上传图片的地址,baseUrl
是图片上传后除了保存在数据库中的文件路径。
这里说下为何须要这个baseUrl
,由于咱们数据库中存储的文件路径是例如201702/12/xxx.jpg
这样的日期+文件名,若是想要完整显示图片,则须要拼接上图片根目录public/upload
变为public/upload/2017/12/xxx.jpg
。这样作的好处是系统迁移十分方便,若是须要从public/uploads/
目录挪到public/images/
目录,只要修改baseUrl
便可。若是数据库存放是绝对路径,之后更改起来会十分麻烦。
fileupload
方法里面有几个参数,其中done表明文件上传完成后所执行的操做,其中data会带上服务器传输过来的一些参数。progressall是图片上传中会执行的函数。最经常使用的也就是这两个,其余还有例如add
添加文件时候执行的,这里不作描述。
前面的代码完成后,点击按钮选择图片后便可上传。接下来就是后台处理图片的任务啦。
咱们新建后台处理图片的方法upload()
,位于index
控制器里面
/** * 处理图片上传 */ public function upload(){ }
这里咱们直接应用Thinkphp上传文件类来处理图片上传问题。
public function upload(){ $upload = new \Think\Upload();// 实例化上传类 $upload->maxSize = 314572800000 ;// 设置附件上传大小 $upload->exts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型 $upload->rootPath = "./Public/uploads/"; // 设置附件上传根目录 $upload->savePath = ""; // 设置附件上传(子)目录 $upload->subName = array('date','Ym/d'); // 上传文件 $info = $upload->upload(); if(!$info) { // 上传错误提示错误信息 $this->error($upload->getError()); } else { $pic_src = $info['upload_img']['savepath'].$info['upload_img']['savename']; $this->ajaxReturn(array("path"=>$pic_src,"status"=>1)); } }
这里设置上传目录为当前目录下的Public
目录下的uploads
文件夹中,设置subName
为日期类型,形如年月/日/文件名
:(2017/02/xxx.jpg
)
简单配置完thinphp上传参数后,开始启用这个强大的upload()
方法上传图片。上传结果会返回到$info
变量中。若是没有返回结果,那么就表示发生了错误,咱们使用$this->error($upload->getError());
将错误专项其余特定错误处理页面。不然咱们向客户端返回文件上传路径和状态。
打印这个info
变量:
array (size=1) 'upload_img' => array (size=9) 'name' => string 'QQ截图20170212181950.png' (length=26) 'type' => string 'image/png' (length=9) 'size' => int 8637 'key' => string 'upload_img' (length=10) 'ext' => string 'png' (length=3) 'md5' => string '6ed1308e73ffd7d8be79ee1bc57bf76f' (length=32) 'sha1' => string '4641dcc5d45eb0af1f1726168cb8c9b25561c0a0' (length=40) 'savename' => string '58a0505fb4661.png' (length=17) 'savepath' => string '201702/12/' (length=10)
咱们发现一个名为upload_img
(这里的upload_img
是上面html代码中file控件的name填写的值)数组中包含不少关于上传文件的信息。咱们取出savepath
和savename
拼接成一个路径返回给客户端。
$pic_src = $info['upload_img']['savepath'].$info['upload_img']['savename']; $this->ajaxReturn(array("path"=>$pic_src,"status"=>1));
同时,这个路径也是最终存入数据库的路径。
后台图片上传完成后,也把图片在服务器上面的路径告诉了前端,如今前端还须要作的任务就是将图片预览图片显示出来。
好,咱们找到js代码中的done
这个方法,直接在里面编写图片显示的程序。首先咱们先打印一下data
参数,看看里面包含了那些信息。
console.log(data);
找到其中的一个属性result
继续打印
console.log(data.result);
此次信息少了很多,可是更加有用了。发现,其中的path就是咱们后台传递过来的图片路径,而status是成功状态。接下来找到html代码中存放预览图的地方。
<div class="thumbnail" id="thumbnail"> <div class="cover"> <img src="__PUBLIC__/img/add_img.png" /> </div> </div>
把图片完整的路径丢进去便可
var path = data.result; $("#thumbnail").html('<div class="up-img"><img style="max-width: 500px;" src="'+baseUrl+path.path+'" /></div>');
图片完美的显示了出来。在上面的js中,咱们还在img外面套了一个class为up-img的div,这个是为了去控制图片位置。
接下来就是提交表单的时候了。可是还有一个问题,咱们图片是显示出来了。可是提交表单时候彷佛很难获取到以前上传的图片路径。因此,还须要js再次操做,将须要保存的图片路径放入input
咱们在页面放一个id为img_url的div方便咱们放置input
$("#img_url").html('<input type="hidden" name="img_url" value="'+ path.path +'" />');
这样,图片上传完成便可自动建立一个input隐藏域方便提交表单。
接下来的事情就简单多了,咱们直接使用异步提交表单。
var submitUrl = "{:U('index/submit')}"; $("#submit").on('click',function () { $.ajax({ url:submitUrl, dataType:'json', type:"post", data:$("#submitForm").serialize(), success:function (e) { if(e.code==1){ alert('ok'); }else{ alert('fail'); } } }); });
接下来就是提交后台处理了。不过在此以前,咱们新建一个数据库用来存储咱们上传的文件路径。
DROP TABLE IF EXISTS `image`; CREATE TABLE `image` ( `img_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '图片ID', `img_url` varchar(255) NOT NULL COMMENT '图片上传路径', `img_name` varchar(15) NOT NULL, `create_time` int(11) NOT NULL COMMENT '图片保存时间', PRIMARY KEY (`img_id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
给出控制器代码:
public function submit() { $img_url = I("post.img_url"); $img_name = I("post.img_name"); $result = M("image")->data(array("img_url"=>$img_url,'img_name'=>$img_url,"create_time"=>time()))->add(); if($result){ echo json_encode(array('code'=>'1')); }else{ echo json_encode(array('code'=>'-1')); } }
多张图片上传,在下篇文章,地址写好了贴。