萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 多檔案上傳完整實作:前端表單、後端處理、安全防護

前端表單:upload_html.php

<!DOCTYPE html>
<html>
<head>
    <title>多檔案上傳</title>
    <script>
    function beforesubmit(form) {
        var indexname = form.indexname.value.replace(/\s/g, "");
        var upfile = form.upfile.value.replace(/\s/g, "");
        if (indexname === "" || upfile === "") {
            alert("目錄名稱或上傳檔案不能為空!");
            return false;
        }
        return true;
    }
    </script>
</head>
<body bgcolor="white">
<br>
<form name="form1" action="upload.php" method="post" enctype="multipart/form-data" onsubmit="return beforesubmit(this)">
    <table cellspacing="1" cellpadding="5" border="0" width="580" bgcolor="#C2E2F5">
        <tr bgcolor="#E3F2FB" align="center">
            <td width="280" height="30">上傳的檔案</td>
        </tr>
        <?php
        // 動態生成 7 個檔案輸入框
        for ($i = 1; $i < 8; $i++) {
            $upfile = "upfile" . $i;
            echo "<tr><td bgcolor=#F5FBFE width=264><input type=file name=$upfile size=25></td></tr>";
        }
        ?>
        <tr bgcolor="#E3F2FB">
            <td colspan="2" height="1" align="center">
                目錄名稱: <input type="text" name="indexname" size="20">
                <input type="submit" value="上傳">
            </td>
        </tr>
    </table>
</form>
</body>
</html>

後端處理:upload.php(需補完)

<?php
// upload.php 核心處理邏輯
$uploadDir = './uploads/';
$indexName = basename(trim($_POST['indexname']));  // 防止路徑遍歷
$targetDir = $uploadDir . $indexName . '/';

if (!is_dir($targetDir)) {
    mkdir($targetDir, 0755, true);
}

$success = 0;
$errors = [];

for ($i = 1; $i <= 7; $i++) {
    $field = "upfile$i";
    if (!isset($_FILES[$field]) || $_FILES[$field]['error'] !== UPLOAD_ERR_OK) {
        continue;  // 未選檔或有錯
    }
    
    $file = $_FILES[$field];
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    $allowed = ['jpg','jpeg','png','gif','pdf','doc','docx','xls','xlsx','zip','rar'];
    
    if (!in_array($ext, $allowed)) {
        $errors[] = "{$file['name']}: 副檔名不允許";
        continue;
    }
    
    // 安全檔名:時間戳 + 隨機數 + 原副檔名
    $newName = date('YmdHis') . '_' . mt_rand(1000,9999) . '.' . $ext;
    $dest = $targetDir . $newName;
    
    if (move_uploaded_file($file['tmp_name'], $dest)) {
        $success++;
        @chmod($dest, 0644);
    } else {
        $errors[] = "{$file['name']}: 移動失敗";
    }
}

echo "成功上傳 $success 個檔案。";
if ($errors) echo "
錯誤: " . implode("
", $errors); ?>

關鍵安全檢查點

  1. 檔案類型驗證:副檔名 + MIME 雙重檢查(finfo_file())
  2. 檔案大小限制:php.ini upload_max_filesize、post_max_size + 程式碼二次檢查
  3. 檔名安全:絕不使用原始檔名,重新命名防止覆蓋、注入、XSS
  4. 目錄遍歷防護:basename()、realpath() 驗證最終路徑在允許目錄內
  5. 執行權限移除:上傳目錄設定 php_flag engine off 或 AddHandler 禁止腳本執行
  6. 病毒掃描:整合 ClamAV 等掃描引擎

現代化改進:HTML5 multiple 屬性

<!-- 單一 input 支援多選 -->
<input type="file" name="upfiles[]" multiple accept="image/*,.pdf,.zip" />

<?php
// 後端對應處理
foreach ($_FILES['upfiles']['tmp_name'] as $key => $tmp) {
    if ($_FILES['upfiles']['error'][$key] === UPLOAD_ERR_OK) {
        // 處理單檔...
    }
}
?>

進階:分塊上傳/斷點續傳

大檔案建議使用:

後端需支援分片合併、MD5 校驗、暫存目錄管理。

copyright © 萬盛學電腦網 all rights reserved