文件上傳是 PHP 開發高頻需求,本文對比兩種經典實現方案,涵蓋錯誤處理、類型驗證、安全命名、目錄掃描等完整流程。
特點:無前端表單,專注後端邏輯,含完整錯誤碼映射、大小限制、類型白名單、時間戳命名、上傳後目錄列表展示。
<?php
// 錯誤碼處理
if ($_FILES['file']['error'] > 0) {
$msg = ['', '文件大小超過服務器限制', '文件太大!', '文件只加載了一部分!', '文件加載失敗!'];
exit('!problem: ' . ($msg[$_FILES['file']['error']] ?? '未知錯誤'));
}
// 大小限制 1MB
if ($_FILES['file']['size'] > 1000000) exit('文件過大!');
// 類型白名單
$allowed = ['image/jpeg' => '.jpg', 'image/gif' => '.gif'];
if (!isset($allowed[$_FILES['file']['type']])) exit('文件不是 JPG 或 GIF 圖片!');
// 安全命名:時間戳 + 正確擴展名
$ext = $allowed[$_FILES['file']['type']];
$filename = 'upfile/' . date("YmdHis") . $ext;
// 移動文件
if (is_uploaded_file($_FILES['file']['tmp_name'])) {
if (!move_uploaded_file($_FILES['file']['tmp_name'], $filename)) exit('移動文件失敗!');
} else exit('problem!');
// 成功輸出
echo "<h1>success!</h1><br>";
echo "文件大小:{$_FILES['file']['size']} 字節<br>";
echo "文件路徑:$filename<hr>";
// 掃描上傳目錄
$dir = opendir('upfile/');
echo "$dir --Listing:<ul>";
while ($file = readdir($dir)) echo "<li>$file</li>";
echo "</ul>";
closedir($dir);
?>
特點:單文件包含表單與處理邏輯,自動創建目錄、JS 提示跳轉、參數傳遞下一頁。
<?php
if (empty($_GET['submit'])) { ?>
<form enctype="multipart/form-data" action="?submit=1" method="post">
Send this file: <input name="filename" type="file">
<input type="submit" value="確定上傳">
</form>
<?php } else {
$path = "uploadfiles/";
if (!file_exists($path)) mkdir($path, 0700);
$allowed = ["image/gif","image/pjpeg","image/png"];
if (!in_array($_FILES["filename"]["type"], $allowed)) exit("格式不對");
if ($_FILES["filename"]["name"]) {
$file1 = $_FILES["filename"]["name"];
$file2 = $path . time() . $file1; // 時間戳防重名
$flag = 1;
}
if ($flag && move_uploaded_file($_FILES["filename"]["tmp_name"], $file2)) {
echo "<script>alert('上傳成功!'); location='add_aaa.php?pname=$file2';</script>";
}
} ?>
upload_max_filesize + 代碼邏輯二次校驗image/pjpeg 為 IE 上傳 JPEG 時的 MIME