php上傳多張圖片代碼服務(wù)端代碼使用PHP編寫文件上傳的幾種方式-事業(yè)家庭php ajax圖片上傳代碼
2022-04-27
首先祝大家端午節(jié)快樂!事業(yè)和家庭更上一層樓。 !
最近遇到一個100M大文件的上傳需求,研究了七牛和騰訊云的分片分片上傳功能。所以這里整理了前端大文件上傳相關(guān)功能的實(shí)現(xiàn)。
在一些業(yè)務(wù)中,上傳大文件是一個比較重要的交互場景,比如導(dǎo)入庫比較大的表數(shù)據(jù),上傳視頻音頻文件等等。如果文件比較大,或者網(wǎng)絡(luò)條件不好,上傳時(shí)間會比較長(需要傳輸?shù)陌容^多,丟包重傳的概率也比較大),用戶無法刷新頁面,只能耐心等待請求完成。 .
下面先從文件上傳方法說起,整理上傳大文件的思路,并給出相關(guān)示例代碼。由于PHP內(nèi)置了方便的文件拆分和拼接方法,所以服務(wù)器端代碼都是用PHP編寫的。
上傳文件的幾種方式
首先,我們來看看上傳文件的幾種方式。
普通表單上傳
使用 PHP 顯示常規(guī)表單上傳是一個不錯的選擇。首先構(gòu)建一個用于文件上傳的表單,并將表單的提交內(nèi)容類型指定為“/form-data”,表示該表單需要上傳二進(jìn)制數(shù)據(jù)。
然后編寫.php上傳文件接收代碼,使用方法(php大法好...)
$imgName = 'IMG'.time().'.'.str_replace('image/','',$_FILES["myfile"]['type']);
$fileName = 'upload/'.$imgName;
// 移動上傳文件至指定upload文件夾下,并根據(jù)返回值判斷操作是否成功
if (move_uploaded_file($_FILES['myfile']['tmp_name'], $fileName)){
echo $fileName;
}else {
echo "nonn";
}
在表單上傳大文件時(shí),很容易遇到服務(wù)器超時(shí)的問題。通過xhr,前端也可以異步上傳文件。一般有兩種思路。
文件編碼上傳
第一個想法是對文件進(jìn)行編碼php上傳多張圖片代碼,然后在服務(wù)器上對其進(jìn)行解碼。主要實(shí)現(xiàn)原理是將圖片轉(zhuǎn)換為傳輸。
var imgURL = URL.createObjectURL(file);
ctx.drawImage(imgURL, 0, 0);
// 獲取圖片的編碼,然后將圖片當(dāng)做是一個很長的字符串進(jìn)行傳遞
var data = canvas.toDataURL("image/jpeg", 0.5);
服務(wù)器端需要做的比較簡單,先解碼再保存圖片
$imgData = $_REQUEST['imgData'];
$base64 = explode(',', $imgData)[1];
$img = base64_decode($base64);
$url = './test.jpg';
if (file_put_contents($url, $img)) {
exit(json_encode(array(
url => $url
)));
}
編碼的缺點(diǎn)是它的體積比原圖大(因?yàn)槿齻€字節(jié)轉(zhuǎn)換成四個字節(jié),編碼后的文字會比原圖大三分之一左右),對于體積。對于大文件,上傳和解析時(shí)間會顯著增加。
除了編碼之外,還可以在前端直接讀取文件內(nèi)容后以二進(jìn)制格式上傳
// 讀取二進(jìn)制文件
function readBinary(text){
var data = new ArrayBuffer(text.length);
var ui8a = new Uint8Array(data, 0);
for (var i = 0; i < text.length; i++){
ui8a[i] = (text.charCodeAt(i) & 0xff);
}
console.log(ui8a)
}
var reader = new FileReader();
reader.onload = function(){
readBinary(this.result) // 讀取result或直接上傳
}
// 把從input里讀取的文件內(nèi)容,放到fileReader的result字段里
reader.readAsBinaryString(file);
異步上傳
主要用于組裝一組用于發(fā)送請求的鍵/值對,可以更靈活的發(fā)送Ajax請求??捎糜谀M表單提交。
let files = e.target.files // 獲取input的file對象
let formData = new FormData();
formData.append('file', file);
axios.post(url, formData);
服務(wù)端處理方式與直接表單請求基本相同。
沒有頁面刷新
在低版本瀏覽器(如IE)上,xhr不支持直接上傳,所以只能使用form上傳文件,而form提交本身會進(jìn)行頁面跳轉(zhuǎn),這是由form的屬性造成的形式。 ,其值為
如果需要讓用戶體驗(yàn)異步上傳文件的感覺,可以指定。將表單的屬性設(shè)置為不可見,則返回的數(shù)據(jù)將被此接受網(wǎng)站模板,