文件上傳是 Web 開發高頻需求,但也是安全隱患高發區。本文提供一個生產可用的上傳處理腳本,涵蓋類型白名單、大小限制、錯誤碼處理、隨機重命名、移動存儲等核心環節,並解析關鍵安全點。
<?php
// 配置區
$allowtype = ['gif', 'png', 'jpg']; // 允許的副檔名
$size = 1000000; // 最大 1MB (字節)
$path = "./uploads"; // 存儲目錄
// 1. 檢查上傳錯誤碼
if ($_FILES['myfile']['error'] > 0) {
echo '上傳錯誤: ';
switch ($_FILES['myfile']['error']) {
case 1: die('超過 php.ini upload_max_filesize');
case 2: die('超過表單 MAX_FILE_SIZE');
case 3: die('文件只被部分上傳');
case 4: die('沒有選擇文件');
default: die('未知錯誤');
}
}
// 2. 驗證文件類型(副檔名)
$ext = strtolower(pathinfo($_FILES['myfile']['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $allowtype)) {
die("副檔名 $ext 不在允許列表中!");
}
/* 進階:也可驗證 MIME 類型
list($maintype, $subtype) = explode('/', $_FILES['myfile']['type']);
if ($maintype === 'text') die('禁止上傳文本文件');
*/
// 3. 驗證文件大小
if ($_FILES['myfile']['size'] > $size) {
die("文件大小超過限制 $size 字節");
}
// 4. 生成安全文件名:時間戳 + 隨機數 + 原副檔名
$filename = date("YmdHis") . rand(100, 999) . "." . $ext;
// 5. 移動文件
if (is_uploaded_file($_FILES['myfile']['tmp_name'])) {
if (!move_uploaded_file($_FILES['myfile']['tmp_name'], $path . '/' . $filename)) {
die('無法將文件移動到目標目錄');
}
} else {
die("非合法上傳文件:{$_FILES['myfile']['name']}");
}
// 6. 成功回饋
echo "文件上傳成功,保存在 $path 目錄下,大小:{$_FILES['myfile']['size']} 字節";
?>
$_FILES['error'] 為 0 才繼續,避免處理損壞/未上傳文件upload_max_filesize + 代碼邏輯雙重保障uploads/ 目錄應設為不可執行(Nginx/Apache 配置 location ~ \.php$ { deny all; })<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
<input type="file" name="myfile">
<input type="submit" value="上傳">
</form>
php.ini file_uploads = On、upload_tmp_dir 可寫post_max_size、max_execution_time、max_input_timeuploads/ 有寫入權限此腳本可直接用於項目,建議進一步封裝為類,增加圖片壓縮、水印、雲存儲對接等擴展功能。