:::

5-2-4 檔案上傳與接收

一、單一個檔案的上傳基本概念

  1. 若表單中有 file 元件,其表單一定要加上 enctype="multipart/form-data"
  2. 假設 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']:和該檔案上傳相關的錯誤代碼。
  3. 上傳的步驟:送出上傳 → 檔案會暫時放到主機的暫存目錄(如:tmp中) → 程式要搬移該暫存檔 $_FILES['image_files']['tmp_name'] 到指定的位置。
  4. 搬移上傳檔方法:
    move_uploaded_file($_FILES['image_files']['tmp_name'], 新路徑檔名);

     

二、多個檔案的上傳基本概念:

  1. 假設 file 欄位名稱為 image_files,多檔上傳的 name 屬性必須加上[]multiple屬性,如:
    <input type="file" class="form-control" id="image_files" name="image_files[]" accept=".jpg,.png" multiple>
  2. 假設選了兩個檔送出後 $_FILES 超級全域變數會變成像這樣(三維陣列):
    1. 第一個檔案
      • $_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]:第一個檔案上傳相關的錯誤代碼。
    2. 第二個檔案
      • $_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]:第二個檔案上傳相關的錯誤代碼。

三、調整我們的上傳語法:

  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)都一併建立

  2. 我們的上傳欄位為:

    <input type="file" class="form-control" id="image_files" name="image_files[]" accept=".jpg,.png" multiple>

    所以需要用 foreach() 迴圈來讀取 $_FILES['image_files'],以便一個檔一個檔抽出來,用 move_uploaded_file() 完成上傳動作。

  3. 目前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;
    			}
    		}
    	}
    }

     

  4. 檔案上傳後,我們必須把所有檔案資訊記錄下來,這樣日後讀出時,才能知道此文章有把些檔案。其中 $media_json 就是用來儲存所有上傳的檔案陣列,$name 是原始檔名,用來作為 $media_json 的陣列索引;$destination 則是真實檔案的完整路徑,如此便可得知這張圖片放在主機的什麼位置。
  5. 最後,只要將 $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]);
    }

     


:::

書籍目錄

展開 | 闔起

http%3A%2F%2Fcampus-xoops.tn.edu.tw%2Fmodules%2Ftad_book3%2Fpage.php%3Ftbdsn%3D2017%26tbsn%3D55

計數器

今天: 3212321232123212
昨天: 2259225922592259
總計: 7952010795201079520107952010795201079520107952010