這篇文章給大家分享的是有關(guān)ThinkPHP5和layui實(shí)現(xiàn)上傳大文件的方法,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲。
為扎囊等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及扎囊網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)、扎囊網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
首先記錄下更改文件上傳大小的一些配置信息.
打開php.ini
file_uploads = on //是否允許通過HTTP上傳文件的開關(guān),默認(rèn)開啟
upload_tmp_dir //臨時(shí)文件儲存的路徑
upload_max_filesize 20M //允許上傳的文件最大值
post_max_size 22M //通過表單POST所能上傳的大小
max_execution_time 600 //單個PHP頁面允許運(yùn)行的最大時(shí)間
max_input_time 600 //單個PHP頁面接收數(shù)據(jù)所需的最大時(shí)間,默認(rèn)60秒
memory_limit 256M //單個PHP頁面執(zhí)行過程中可占用的最大內(nèi)存,默認(rèn)8M
通過更改上述的配置就可以調(diào)整允許文件上傳的大小。(有的還需要調(diào)整服務(wù)器的一些配置)
補(bǔ)充:413錯誤 如果服務(wù)器是nginx的話,需要更改配置nginx_conf 中的client_max_body_size 24M,設(shè)置接收客戶端發(fā)送過來包的最大值。記得放在http里,重啟服務(wù)器,用restart,不要用reload。
接著開始實(shí)現(xiàn)文件的分割上傳。
文件通過HTML的input標(biāo)簽的file來選擇文件上傳。通過H5新對象FileReader。就像字面上的意思一樣FileRaeder對象就是一個讀取本地文件的對象。FileReader對象可以將本地文件讀取后以base64位的編碼返回。(具體有關(guān)FileReader對象的使用,請自行百度,或者閱讀以下博文,寫的很具體。
實(shí)際開發(fā)
第一次嘗試
通過input file標(biāo)簽來選擇文件
采用FileReader對象對文件進(jìn)行讀取
通過ajax異步將文件的base64編碼發(fā)送給服務(wù)端
服務(wù)端接收后對編碼進(jìn)行解碼并保存到文件中。
測試結(jié)果失敗,當(dāng)文件過大時(shí)所編碼的長度也越長,通過ajax異步提交參數(shù)的最大上線為8000個字節(jié)。
第二次嘗試
在第一次的基礎(chǔ)上對所獲取到的base64編碼進(jìn)行分割上傳
將所獲取的base64編碼字符串分成幾份并進(jìn)行編號,在循環(huán)調(diào)用ajax進(jìn)行發(fā)送
服務(wù)端接收到后對數(shù)據(jù)進(jìn)行解碼,以編號進(jìn)行命名
接收完所有小文件后,調(diào)用后臺方法將小文件進(jìn)行合并
測試結(jié)果失敗,當(dāng)上傳文件超過1G時(shí),瀏覽器就崩潰了。應(yīng)該是在讀取文件時(shí),文件過大,一次性讀出返回base64編碼過大,導(dǎo)致頁面崩潰。
第三次嘗試
在第二次的基礎(chǔ)上想著在讀取文件獲取編碼的過程也進(jìn)行分批讀取來避免一次性讀取過大的文件導(dǎo)致頁面崩潰。
這邊就要使用到H5的file.slice()來對文件進(jìn)行分塊,從而實(shí)現(xiàn)分批讀取分批上傳。
通過FlieReader對象來讀取文件快
通過ajax將base64編碼異步發(fā)送到服務(wù)端
服務(wù)端接收數(shù)據(jù)進(jìn)行解碼和文件保存
測試成功,測試上傳了快4G的文件。
(由于將文件進(jìn)行了分段,所以在上傳大文件時(shí)會發(fā)起大量的ajax請求,產(chǎn)生大量的并發(fā),可能會導(dǎo)致頁面再次崩潰。所以我才用錯開請求的方式。減慢產(chǎn)生ajax請求的速度。)
具體實(shí)現(xiàn)代碼
接下來貼點(diǎn)代碼
前端框架:layui
后端框架:tp5
頁面代碼:
- //視頻上傳會比較久(上傳完會有提示)
js代碼:
$('.video-upload-file').on('change',function(){ layer.msg('正在提交視頻......'); //隱藏按鈕,顯示進(jìn)度條 $('.layui-upload-video').hide(); $('.layui-progress-ads').show(); var loads_video = layer.load(2,{shade: [0.2, '#3a3535']}); //產(chǎn)生加載圈,禁止用戶其他操作 var thisFile = $(this); var reader=new FileReader(); var file_size = this.files[0].size; //文件大小 var limit = 8388608; //每次讀取文件的大小 // var limit = 1048000; //每次讀取文件的大小 var up_count = Math.ceil(file_size/limit); //總上傳次數(shù) var type = this.files[0].type.substr(this.files[0].type.indexOf('/')+1); //文件類型 var success_num = 0; //用于存放上傳成功的數(shù)據(jù)的id var check = 1; //防止多次合并 console.log('文件大?。?#39;+this.files[0].size); console.log('文件類型:'+type); console.log('分割上傳次數(shù):'+up_count); //分段讀取文件 readFile(this.files[0], 0, limit); function readFile(file, num, limit){ // console.log('第'+num+'次:'+num*limit); reader.readAsDataURL(file.slice(num*limit, (num+1)*limit)); reader.onload = function(e){ console.log(reader.result.length); console.log(reader.result); //異步base64的數(shù)據(jù)傳輸?shù)椒?wù)器 ajax_way(reader.result, name, num+1, thisFile); if((num+1)*limit <= file_size){ readFile(file, num+1, limit); } } } function ajax_way(data,name,num, thisFile){ //避免一次性生成太多的請求 if(num+1 > 60){ // console.log('等待兩秒'); sleep(6000); // console.log('等待結(jié)束'); } $.ajax({ url: "= url('admin/video/up_mfile');?>", type: "POST", data: {video:data,name:name,num:num}, // async:false, //是否采用同步,串行發(fā)送請求 success: function (data) { if(data.code == 1){ //上傳成功,成功次數(shù)加一 success_num++; console.log(num+'完成'); console.log('已完成:'+success_num+'/'+up_count); //計(jì)算完成的百分比 var precentage = Math.ceil((success_num/up_count)*100); //更改進(jìn)度條顯示 $('.layui-progress-ads-btn').attr('lay-percent', precentage+'%'); $('.layui-progress-ads-btn').css('width', precentage+'%'); $('.layui-progress-text').html(precentage+'%'); //如果分割文件都上傳了則調(diào)用接口合并文件 if(success_num == up_count && check == 1){ check = 0; success_num = 0; merge_mfile(name, up_count, thisFile, type); } } }, error:function(e){ console.log('出錯了:'+num); //傳輸出錯則重新上傳 ajax_way(data, name, num, thisFile); } }); } //合并文件 function merge_mfile(name, count, thisFile, type){ $.ajax({ url:"= url('admin/video/merge_mfile');?>", data:{name:name, count:count, type:type}, type:"POST", success:function(data){ if (data.code==1){ layer.close(loads_video); layer.msg('視頻提交成功'); thisFile.siblings('.video-link-id').val(data.data); }else{ layer.msg('視頻提交異常請重新提交'); //顯示按鈕,隱藏進(jìn)度條 $('.layui-upload-video').show(); $('.layui-progress-ads').hide(); //將進(jìn)度條置零 $('.layui-progress-ads-btn').attr('lay-percent', '0%'); $('.layui-progress-ads-btn').css('width', '0%'); $('.layui-progress-text').html('0%'); //清空已選中的文件 var file = $(".layui-upload-video-file-btn"); file.after(file.clone().val("")); file.remove(); } } }) } function sleep(n) { //n表示的毫秒數(shù) var start = new Date().getTime(); while (true) if (new Date().getTime() - start > n) break; } return false; });
看完這篇文章,你們學(xué)會ThinkPHP5和layui實(shí)現(xiàn)上傳大文件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀。