最小化實現
send.htm(上傳表單)
<form enctype="multipart/form-data" action="get.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
上傳文件:<input name="userfile" type="file">
<input type="submit" value="上傳">
</form>
get.php(接收處理)
<?php
// PHP 4.1+ 使用 $_FILES 超全域陣列
$tmpName = $_FILES['userfile']['tmp_name'];
$name = $_FILES['userfile']['name'];
$size = $_FILES['userfile']['size'];
$error = $_FILES['userfile']['error'];
if ($error !== UPLOAD_ERR_OK) {
die('上傳錯誤代碼: ' . $error);
}
$destDir = 'uploads/';
if (!is_dir($destDir)) mkdir($destDir, 0755, true);
$destPath = $destDir . basename($name);
// 防止同名覆蓋:可加時間戳/隨機字串前綴
if (move_uploaded_file($tmpName, $destPath)) {
echo '上傳成功!文件保存至: ' . $destPath;
} else {
echo '上傳失敗!';
}
?>
關鍵配置項(php.ini)
| 指令 | 說明 | 建議值 |
| file_uploads | 啟用上傳支援 | On |
| upload_tmp_dir | 臨時文件目錄(需可寫) | /tmp 或自定義目錄 |
| upload_max_filesize | 單文件最大體積 | 10M |
| post_max_size | POST 總體積上限(需 ≥ upload_max_filesize) | 12M |
| max_file_uploads | 單次請求最大文件數 | 20 |
| max_input_time | 解析輸入最大秒數(大文件需調大) | 60 |
安全防護清單
- 驗證 MIME 類型:
$_FILES['userfile']['type'] 可偽造,必須用 finfo_file() 檢測真實類型
- 檢查副檔名:白名單機制(如
['jpg','png','gif','pdf']),拒絕 .php、.exe、.sh 等可執行腳本
- 重命名存儲:
md5(uniqid()).'.'.$ext,避免覆蓋、路徑遍歷、腳本執行
- 存儲目錄不可執行:Nginx/Apache 配置
location ~ \.php$ { deny all; } 或放置於 Web 根目錄外
- 限制上傳大小:前端
MAX_FILE_SIZE 僅提示,後端必須強制校驗 $_FILES['size']
- 病毒掃描:生產環境接入 ClamAV 或云端安全 API
- 權限最小化:上傳目錄僅
www-data 可寫,不可讀取執行
進階功能擴展
- 分片上傳(Plupload、WebUploader)支援大文件斷點續傳
- 圖片自動縮略/水印(GD/Imagick)
- 雲存儲直傳(OSS、COS、S3 簽名直傳,減輕應用服務器帶寬)
- 上傳進度條(Session 上傳進度 / AJAX 輪詢 / XHR2 progress 事件)