在 PHP 開發中,檔案上傳是極為常見的功能。而 $_FILES 超全域陣列則是處理上傳檔案資訊的核心。本文將系統整理 $_FILES 的結構、錯誤代碼常數,並針對臨時檔案處理、表單編碼、版本差異等實戰陷阱進行深度解析,助你避開常見坑點。
假設表單的檔案輸入欄位名稱為 myFile,上傳後 $_FILES['myFile'] 將包含以下鍵值:
photo.jpg)。image/jpeg),不可完全信任,建議伺服端再驗證。php.ini 的 upload_tmp_dir 設定;注意 putenv() 無法修改此設定。0。以下常數自 PHP 3.0 起可用,建議直接使用常數而非數值,提升可讀性:
| 常數 | 值 | 說明 |
|---|---|---|
| UPLOAD_ERR_OK | 0 | 無錯誤,上傳成功。 |
| UPLOAD_ERR_INI_SIZE | 1 | 超過 php.ini 的 upload_max_filesize 限制。 |
| UPLOAD_ERR_FORM_SIZE | 2 | 超過 HTML 表單 MAX_FILE_SIZE 隱藏欄位指定的值。 |
| UPLOAD_ERR_PARTIAL | 3 | 檔案僅部分上傳(網路中斷等)。 |
| UPLOAD_ERR_NO_FILE | 4 | 沒有檔案被上傳(用戶未選檔)。 |
| UPLOAD_ERR_NO_TMP_DIR | 6 | 找不到臨時資料夾(PHP 5.0.3 新增)。 |
| UPLOAD_ERR_CANT_WRITE | 7 | 寫入臨時檔案失敗(PHP 5.1.0 新增)。 |
| UPLOAD_ERR_EXTENSION | 8 | PHP 擴展阻止檔案上傳(PHP 5.2.0 新增)。 |
腳本執行結束後,臨時目錄下的檔案會被自動刪除,**無論上傳是否成功**。因此必須在腳本結束前,使用 move_uploaded_file()(推薦,會檢查是否為真實上傳檔案)或 copy() 將檔案移至永久儲存位置。
// 正確範例
$dest = '/var/www/uploads/' . basename($_FILES['myFile']['name']);
if (move_uploaded_file($_FILES['myFile']['tmp_name'], $dest)) {
echo '上傳成功';
} else {
echo '移動失敗';
}
enctype="multipart/form-data"這是最常見的新手錯誤。若缺少此屬性,$_FILES 將為空,無法獲取任何檔案資訊。
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="myFile">
<input type="submit" value="上傳">
</form>
$HTTP_POST_FILES vs $_FILES$HTTP_POST_FILES,**非**自動全域變數,需在函式中宣告 global $HTTP_POST_FILES。$_FILES,為超全域變數,直接可用。$HTTP_POST_FILES。現代專案請直接使用 $_FILES,忽略舊版寫法。
$_FILES['type'],改用 finfo_file() 或 mime_content_type() 解析實際內容。php.ini 設定 upload_max_filesize、post_max_size,並在程式碼二次驗證。uniqid() . '_' . 原檔名),避免覆蓋與路徑遍歷攻擊。getimagesize() 驗證;其他類型建議整合防毒掃描。掌握 $_FILES 的結構與錯誤代碼,配合正確的表單編碼與臨時檔案處理流程,即可構建穩健的檔案上傳功能。記住:永遠在伺服端驗證,不要信任客戶端資料。