首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 檔案上傳完整指南:從表單建構到多檔案處理實戰

     編輯:PHP 相關知識

檔案上傳是 Web 開發核心功能之一。本文循序漸進說明:HTML 表單關鍵屬性、$_FILES 陣列結構、核心參數設定、單檔/多檔上傳實作、安全防護與常見錯誤碼對照。

一、HTML 表單必要條件

<form action="upload.php" method="post" enctype="multipart/form-data">
    <!-- 限制上傳大小(建議值,瀏覽器端攔截,非絕對安全) -->
    <input type="hidden" name="MAX_FILE_SIZE" value="2000000">
    <input type="file" name="userfile">
    <input type="submit" value="上傳檔案">
</form>

關鍵點:

  • enctype="multipart/form-data":必須,否則 $_FILES 為空。
  • MAX_FILE_SIZE:僅為瀏覽器建議值,易被繞過,後端必須驗證。

二、$_FILES 陣列結構詳解

假設 input name="userfile":

鍵名說明
$_FILES['userfile']['name']用戶端原始檔名
$_FILES['userfile']['type']MIME 類型(瀏覽器提供,不可全信)
$_FILES['userfile']['size']檔案大小(Bytes)
$_FILES['userfile']['tmp_name']伺服器暫存路徑
$_FILES['userfile']['error']錯誤代碼(見下表)

錯誤代碼對照表

代碼常數原因
0UPLOAD_ERR_OK上傳成功
1UPLOAD_ERR_INI_SIZE超過 php.ini upload_max_filesize
2UPLOAD_ERR_FORM_SIZE超過表單 MAX_FILE_SIZE
3UPLOAD_ERR_PARTIAL僅部分上傳
4UPLOAD_ERR_NO_FILE未選擇檔案
6UPLOAD_ERR_NO_TMP_DIR缺少暫存目錄
7UPLOAD_ERR_CANT_WRITE寫入磁碟失敗
8UPLOAD_ERR_EXTENSION擴展模組中斷上傳

三、PHP 核心設定參數

修改 php.ini 或 .user.ini:

指令預設值說明
file_uploadsOn啟用 HTTP 上傳
upload_max_filesize2M單檔最大值
post_max_size8MPOST 總資料大小,需 > upload_max_filesize
upload_tmp_dir系統預設暫存目錄,需可寫入權限
max_file_uploads20單次請求最大檔案數
max_input_time60解析輸入資料最長秒數(大檔需調大)
memory_limit128M腳本記憶體上限

四、單檔上傳核心代碼

<?php
$targetDir = __DIR__ . '/uploads/';
if (!is_dir($targetDir)) mkdir($targetDir, 0755, true);

$file = $_FILES['userfile'] ?? null;
if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
    die('上傳失敗,錯誤代碼:' . ($file['error'] ?? '未知'));
}

// 安全驗證
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
$maxSize = 2 * 1024 * 1024; // 2MB

if (!in_array($file['type'], $allowedTypes)) die('檔案類型不允許');
if ($file['size'] > $maxSize) die('檔案過大');

// 產生唯一檔名防覆蓋
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
$newName = uniqid('upload_', true) . '.' . $ext;
$dest = $targetDir . $newName;

if (move_uploaded_file($file['tmp_name'], $dest)) {
    chmod($dest, 0644);
    echo "上傳成功:$newName";
} else {
    echo "移動檔案失敗,請檢查目錄權限";
}
?>

五、多檔案上傳實作

HTML:<input type="file" name="files[]" multiple>

<?php
$targetDir = __DIR__ . '/uploads/';
$results = ['success' => [], 'failed' => []];

foreach ($_FILES['files']['tmp_name'] as $idx => $tmpName) {
    $error = $_FILES['files']['error'][$idx];
    if ($error !== UPLOAD_ERR_OK) {
        $results['failed'][] = ['name' => $_FILES['files']['name'][$idx], 'error' => $error];
        continue;
    }

    $name = $_FILES['files']['name'][$idx];
    $size = $_FILES['files']['size'][$idx];
    $type = $_FILES['files']['type'][$idx];

    // 同單檔驗證邏輯...
    $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    $allowedExt = ['jpg','jpeg','png','gif','pdf'];
    if (!in_array($ext, $allowedExt) || $size > 2*1024*1024) {
        $results['failed'][] = ['name' => $name, 'error' => '驗證失敗'];
        continue;
    }

    $newName = uniqid('multi_', true) . '.' . $ext;
    if (move_uploaded_file($tmpName, $targetDir . $newName)) {
        $results['success'][] = $newName;
    } else {
        $results['failed'][] = ['name' => $name, 'error' => '移動失敗'];
    }
}

echo json_encode($results, JSON_UNESCAPED_UNICODE);
?>

六、安全防護清單

  1. 驗證 MIME 與副檔名:雙重檢查,使用 finfo_file() 偵測真實類型。
  2. 檔名重命名:避免覆蓋、路徑遍歷、特殊字元問題。
  3. 儲存於 Web 根目錄外:或以 .htaccess / Nginx 規則禁止腳本執行。
  4. 限制檔案大小與數量:防止 DoS。
  5. 掃描惡意內容:整合 ClamAV 或雲端掃毒 API。
  6. CSRF 保護:表單加入 Token 驗證。

七、大檔案上傳優化

  • 前端分片上傳 + 後端合併。
  • 調大 max_input_time、max_execution_time。
  • 使用 Nginx client_max_body_size 與 proxy_request_buffering off。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved