圖片上傳是不少網站必備的功能之一,異步多圖上傳也是不少初學者比較頭疼的問題。因此今天咱們就使用比較熱門的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')); } }
多張圖片上傳,在下篇文章,地址寫好了貼。