:::
5-2-4 檔案上傳與接收
一、單一個檔案的上傳基本概念
- 若表單中有
file元件,其表單一定要加上enctype="multipart/form-data" - 假設
file欄位名稱為image_files(先將[]及multiple拿掉,也就是只上傳一個檔),如此送出後會產生一組$_FILES超級全域變數(二維陣列):$_FILES['image_files']['name']:上傳檔案原始名稱。$_FILES['image_files']['type']:檔案的 MIME 類型,例如“image/gif”。$_FILES['image_files']['size']:已上傳檔案的大小,單位為bytes。$_FILES['image_files']['tmp_name']:檔案被上傳後的臨時檔案名。$_FILES['image_files']['error']:和該檔案上傳相關的錯誤代碼。
- 上傳的步驟:送出上傳 → 檔案會暫時放到主機的暫存目錄(如:tmp中) → 程式要搬移該暫存檔
$_FILES['image_files']['tmp_name']到指定的位置。 - 搬移上傳檔方法:
move_uploaded_file($_FILES['image_files']['tmp_name'], 新路徑檔名);
二、多個檔案的上傳基本概念:
- 假設 file 欄位名稱為
image_files,多檔上傳的name屬性必須加上[]及multiple屬性,如:<input type="file" class="form-control" id="image_files" name="image_files[]" accept=".jpg,.png" multiple> - 假設選了兩個檔送出後
$_FILES超級全域變數會變成像這樣(三維陣列):- 第一個檔案
$_FILES['image_files']['name'][0]:第一個檔案原始名稱。$_FILES['image_files']['type'][0]:第一個檔案的 MIME 類型,例如“image/gif”。$_FILES['image_files']['size'][0]:第一個檔案的大小,單位為bytes。$_FILES['image_files']['tmp_name'][0]:第一個檔案被上傳後的臨時檔案名。$_FILES['image_files']['error'][0]:第一個檔案上傳相關的錯誤代碼。
- 第二個檔案
$_FILES['image_files']['name'][1]:第二個檔案原始名稱。$_FILES['image_files']['type'][1]:第二個檔案的 MIME 類型,例如“image/gif”。$_FILES['image_files']['size'][1]:第二個檔案的大小,單位為bytes。$_FILES['image_files']['tmp_name'][1]:第二個檔案被上傳後的臨時檔案名。$_FILES['image_files']['error'][1]:第二個檔案上傳相關的錯誤代碼。
- 第一個檔案
三、調整我們的上傳語法:
- 先用 file_exists() 檢查目錄是否存在,若不存在就建立上傳目錄。而目錄會根據文章
id編號來建立子目錄,例如id=12的文章,其目錄路徑就是/uploads/12/,這樣可以避免圖檔互相覆蓋,避免誤刪或者未來要刪除文章時也比較容易刪掉附檔。// 獲取插入的ID $id= $pdo->lastInsertId(); // 創建上傳目錄 $upload_dir = "uploads/{$id}/"; if (!is_dir($upload_dir)) { mkdir($upload_dir, 0777, true); }其中
0777是指任何人都可以寫入,而最後的true則是連同父目錄(uploads)都一併建立 -
我們的上傳欄位為:
<input type="file" class="form-control" id="image_files" name="image_files[]" accept=".jpg,.png" multiple>所以需要用
foreach()迴圈來讀取$_FILES['image_files'],以便一個檔一個檔抽出來,用 move_uploaded_file() 完成上傳動作。 -
目前AI給的上傳檔案的語法:
// 處理文件上傳 if ($_POST['upload_type'] === 'image' && !empty($_FILES['image_files']['name'][0])) { foreach ($_FILES['image_files']['name'] as $key => $name) { $tmp_name = $_FILES['image_files']['tmp_name'][$key]; $error = $_FILES['image_files']['error'][$key]; if ($error === UPLOAD_ERR_OK) { $extension = pathinfo($name, PATHINFO_EXTENSION); $new_name = uniqid() . '.' . $extension; $destination = $upload_dir . $new_name; if (move_uploaded_file($tmp_name, $destination)) { $media_json[$name] = $destination; } } } } - 檔案上傳後,我們必須把所有檔案資訊記錄下來,這樣日後讀出時,才能知道此文章有把些檔案。其中
$media_json就是用來儲存所有上傳的檔案陣列,$name是原始檔名,用來作為$media_json的陣列索引;$destination則是真實檔案的完整路徑,如此便可得知這張圖片放在主機的什麼位置。 - 最後,只要將
$media_json資料用 json_encode() 編成JSON格式(加上JSON_UNESCAPED_UNICODE參數可以讓中文正確呈現,否則會用Unicode編碼,不過JSON_UNESCAPED_UNICODE太難記,所以可以直接輸入其對應值256就好),再寫進資料庫就OK囉!// 更新media欄位 if (!empty($media_json)) { $update_sql = "UPDATE school_news SET media = ? WHERE id = ?"; $update_stmt = $pdo->prepare($update_sql); $json_data = json_encode($media_json, 256); $update_stmt->execute([$json_data, $id]); }
5-2-3 建立縮圖並產生json資料