本文接下來的內容講的是如何透過php實現圖片的上傳與下載
構建上傳文件前端頁面
這裡我借助bootstrap前端框架以及fontawesome圖標庫,內容很簡單就一個圖片上傳框以及一個提交按鈕,程式碼如下:
<!--form.php--> <div class="container"> <form action="upload_del.php" method="post" enctype="multipart/form-data" class="form-horizontal"> <input type="hidden" name="MAX_FILE_SIZE" value="2097152"> <div class="btn btn-success fileBox"> <span> <i class="fa fa-file-image-o"></i> 上传图片 </span> <input type="file" accept="image/*" name="file[]" multiple> </div> <input type="submit" value="上传" class="btn btn-primary"> </form> </div>
其中:
隱藏域主要是用來現在檔案上傳大小的,設定為2M=>2*1024*1024 =>2097152
設定接收檔案類型為圖片格式,可多張圖片上傳,注意name屬性值為file[]時伺服器可接收多個圖片
後台伺服器圖片上傳處理
檔案從前端上傳到伺服器之後,伺服器得到上傳檔案的資訊之後進行處理,主要包括以下幾點:
首先圖片上傳有沒有錯誤,如果沒有下一步,有則回傳錯誤訊息
偵測檔案上傳的大小
偵測檔案類型,看是否為圖片類型
偵測是否為真實圖片類型,有些圖片可能是偽造的,例如我們把一個文字檔案副檔名修改成圖片類型,上述幾條照樣通過
移動伺服器臨時文件到指定目錄
針對2、3步有人可能會問,我們不是前端已經在隱藏域中限制上傳大小了嘛,而且也設置了文件的接收類型,為什麼伺服器還要進行驗證?有句話是這麼說的,伺服器永遠不要相信客戶端傳過來的數據,有過程式設計經驗的人都知道,我們可以在瀏覽器修改前端的頁面結構以及內容,而且還可以偽造數據,前端的驗證只是起到過濾的作用,並不能一勞永逸,伺服器還是得驗證前台傳過來的資料
接下來直接看程式碼,處理檔案上傳函數upload_fun.php:
<?php /** * 获取上传文件信息,处理单文件和多文件上传 * @return array 上传文件信息 */ function getFiles() { $i = 0; $files=[]; foreach ($_FILES as $file) { if (is_string($file["name"])) { $files[$i] = $file; $i++; } elseif (is_array($file["name"])) { foreach ($file["name"] as $key => $val) { $files[$i]["name"] = $file["name"][$key]; $files[$i]["type"] = $file["type"][$key]; $files[$i]["tmp_name"] = $file["tmp_name"][$key]; $files[$i]["error"] = $file["error"][$key]; $files[$i]["size"] = $file["size"][$key]; $i++; } } } return $files; } /** * 获取文件的扩展名 * @param $filename:文件名 * @return string 扩展名 */ function getExt($filename) { return strtolower(pathinfo($filename, PATHINFO_EXTENSION)); } /** * 生成唯一字符串作为文件名 * @return string 唯一文件名 */ function getUniName() { return md5(uniqid(microtime(true), true)); } /** * 上传文件主处理模块 * @param $fileInfo:文件信息 * @param string $path:上传文件路径 * @param bool $flag:是否开启验证是否为真实图片 * @param int $maxSize:文件最大上传大小 * @param array $allowExt:允许的文件扩展名 * @return array 信息 */ function upload_file($fileInfo, $path = "./uploads", $flag = true, $maxSize = 2*1024 * 1024, $allowExt = ["jpeg", 'jpg', 'png', 'gif']) { $res = []; if ($fileInfo['error'] == UPLOAD_ERR_OK) { $ext = getExt($fileInfo["name"]); $uniName = getUniName(); $dest = $path . "/" . $uniName . "." . $ext; //检测上传文件大小 if ($fileInfo["size"] > $maxSize) { $res["msg"] = $fileInfo["name"] . "上传文件过大"; } //上传文件类型 if (!in_array($ext, $allowExt)) { $res["msg"] = $fileInfo["name"] . "非法文件类型"; } //检测是否为真实图片 if ($flag) { if (!getimagesize($fileInfo["tmp_name"])) { $res["mes"] = $fileInfo["name"] . "不是真实图片"; } } if ($res) return $res; if (!file_exists($path)) { mkdir($path, 0777, true); } if (!@move_uploaded_file($fileInfo["tmp_name"], $dest)) { $res['msg'] = $fileInfo["name"] . "文件上传失败"; } else { $res["msg"] = $fileInfo["name"] . "文件上传成功"; $res["dest"] = $dest; } return $res; } else { //判断错误信息 switch ($fileInfo["error"]) { case 1: $res["mes"] = "上传文件超过php配置文件中upload_max_filesize选项的值"; break; case 2: $res["mes"] = "超过了表单MMAX_FILE_SIZE限制的大小"; break; case 3: $res["mes"] = "文件部分被上传"; break; case 4: $res["mes"] = "没有选择上传文件"; break; case 6: $res["mes"] = "没有找到临时目录"; break; case 7: $res['msg'] = "文件写入失败"; break; case 8: $res["mes"] = "系统错误"; break; } return $res; } }
伺服器接收上傳檔案呼叫處理檔案上傳函數upload_fun. php進行處理:
<?php //upload_del.php require_once "upload_fun.php"; $files = getFiles(); foreach ($files as $fileInfo){ $res = upload_file($fileInfo); echo $res["msg"].'<br>'; $uploadFiles[] = $res["dest"]; } $uploadFiles = array_values(array_filter($uploadFiles)); print_r($uploadFiles);
$uploadFiles = array_values(array_filter($uploadFiles));這句話主要是因為上傳多個檔案時可能會有個別檔案出錯而上傳失敗導致$uploadFiles[]中的某個值是空值,所以我們需要對其進行過濾並賦值給一個新數組