文件上傳是 Web 應用的基礎功能,但涉及客戶端限制、服務端配置、安全校驗、存儲策略等多個環節。本系列分上中下三篇,系統講解從原理到生產級封裝的完整知識體系。上篇聚焦核心流程、$_FILES 結構、php.ini 關鍵配置與客戶端偽安全性。
<input type="file"> 選擇文件提交表單(enctype="multipart/form-data");/tmp/phpXXXXXX);$_FILES 超全局變量填充臨時文件信息;move_uploaded_file() 或 copy() 將臨時文件移動到**持久化存儲目錄**;單文件上傳時 $_FILES['fieldName'] 為一維關聯數組:
| 鍵名 | 含義 | 示例 |
|---|---|---|
name | 客戶端原始文件名 | avatar.png |
type | 瀏覽器報告的 MIME 類型(不可信) | image/png |
tmp_name | 服務端臨時文件絕對路徑(核心) | /tmp/phpA1b2C3 |
size | 文件大小(字節) | 102400 |
error | 錯誤碼(0 成功,非 0 見下表) | 0 |
| 常量 | 值 | 含義 |
|---|---|---|
UPLOAD_ERR_OK | 0 | 上傳成功 |
UPLOAD_ERR_INI_SIZE | 1 | 超過 php.ini upload_max_filesize |
UPLOAD_ERR_FORM_SIZE | 2 | 超過表單 MAX_FILE_SIZE |
UPLOAD_ERR_PARTIAL | 3 | 僅部分上傳 |
UPLOAD_ERR_NO_FILE | 4 | 未選擇文件 |
UPLOAD_ERR_NO_TMP_DIR | 6 | 缺少臨時目錄 |
UPLOAD_ERR_CANT_WRITE | 7 | 寫入磁盤失敗 |
UPLOAD_ERR_EXTENSION | 8 | PHP 擴展阻止上傳 |
| 指令 | 默認值 | 建議生產值 | 說明 |
|---|---|---|---|
file_uploads | On | On | 總開關 |
upload_tmp_dir | 系統臨時目錄 | /var/www/tmp_upload | 專用臨時目錄,需 PHP 進程用戶可寫 |
upload_max_filesize | 2M | 20M | 單文件上限,配合 Nginx client_max_body_size |
max_file_uploads | 20 | 50 | 單請求最大文件數 |
post_max_size | 8M | 25M | POST 總體上限,**必須 > upload_max_filesize** |
max_execution_time | 30 | 300 | 大文件上傳需更長執行時間 |
max_input_time | 60 | 300 | 解析輸入數據時間 |
memory_limit | 128M | 256M | 單腳本內存上限 |
| 屬性/手段 | 代碼 | 局限性 |
|---|---|---|
MAX_FILE_SIZE 隱藏域 | <input type="hidden" name="MAX_FILE_SIZE" value="2097152"> | 瀏覽器**不強制執行**,用戶可篡改/移除 |
accept 屬性 | <input type="file" accept="image/*"> | 僅過濾文件選擇對話框,不阻止提交 |
| JS 前端校驗 | file.size > 2*1024*1024 | 繞過極簡單(禁用 JS、修改請求) |
結論:所有安全校驗**必須在服務端**執行,客戶端僅作為體驗優化。
MAX_FILE_SIZE=2M,php.ini upload_max_filesize=10M:$_FILES['error']==2(表單限制),返回「超過表單限制」;$_FILES['error']==1(ini 限制),腳本可能未執行即報錯。下篇將實戰封裝生產級上傳類,涵蓋類型白名單、魔數檢測、唯一命名、目錄自動創建、錯誤碼多語言映射等核心功能。