Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> 電腦軟體教學 >> 伺服器技術 >> 關於伺服器

Nginx + PHP 大檔案上傳完整配置指南:client_max_body_size 核心參數

編輯:關於伺服器

問題現象

  • 上傳 > 1MB 檔案失敗 (Nginx 預設限制)
  • PHP 端無任何錯誤日誌 (請求被 Nginx 攔截)
  • 瀏覽器顯示 413 Request Entity Too Large 或連線重置

三層配置必須同步調整

層級參數預設值建議值 (30MB 範例)說明
Nginxclient_max_body_size1m30mHTTP 請求體最大值,超過直接 413
PHPupload_max_filesize2M30M單一檔案上傳上限
PHPpost_max_size8M35MPOST 總資料上限,**必須 > upload_max_filesize**

Nginx 配置

# nginx.conf http 區塊 (全域生效)
http {
    client_max_body_size 30m;
    client_body_timeout 300s;  # 上傳超時,大檔案需調大
    client_body_buffer_size 128k;  # 緩衝區,大檔案可調至 1m
    ...
}

# 或 server/location 區塊 (精細控制)
server {
    location /upload/ {
        client_max_body_size 100m;  # 僅上傳介面放寬
    }
}

PHP 配置 (php.ini)

file_uploads = On
upload_tmp_dir = /var/tmp/php_upload  # 獨立分區、足夠空間、權限正確
upload_max_filesize = 30M
post_max_size = 35M
max_execution_time = 600      # 腳本執行上限秒數
max_input_time = 600          # 接收資料上限秒數
memory_limit = 128M           # 腳本記憶體上限,大檔案處理需足夠
; 建議:啟用 OPcache 加速
opcache.enable=1
opcache.memory_consumption=128

大檔案 (>100MB) 進階優化

1. 分片上傳 (前端切片 + 後端合併)

  • 前端:WebUploader / Plupload / Uppy 切片 (5MB/片)
  • 後端:暫存分片 → 全部上傳完成 → 合併 → 校驗 MD5
  • 優點:斷點續傳、並行上傳、繞過單請求限制、進度條精確

2. Nginx 上傳模組 (ngx_http_upload_module)

# 編譯時加入 --add-module=../ngx_http_upload_module
location /upload {
    upload_pass /php/merge_handler.php;
    upload_store /var/tmp/nginx_upload 1 2;
    upload_store_access user:rw;
    upload_set_form_field $upload_field_name.name "$upload_file_name";
    upload_set_form_field $upload_field_name.path "$upload_tmp_path";
    upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
    upload_pass_form_field "^submit$|^description$";
    upload_cleanup 400 404 499 500-505;
}

優點:Nginx 層面直接處理上傳、不佔用 PHP Worker、高併發極致效能

3. 直接上傳雲端儲存 (S3/OSS/COS 簽名直傳)

  • 後端產生預簽名 URL → 前端直傳雲端 → 回調通知後端
  • 完全卸載應用伺服器頻寬與磁碟 IO

常見坑點排查清單

  1. client_max_body_size 寫在 http 而非 server,被預設值覆蓋
  2. post_max_size < upload_max_filesize 導致大檔案截斷
  3. upload_tmp_dir 磁碟空間不足 / 權限錯誤 (需 www-data 可寫)
  4. PHP-FPM request_terminate_timeout 過小,大檔案上傳中被殺
  5. 負載均衡/CDN 層面也有大小限制 (AWS ALB 1MB、Cloudflare 100MB 免費版)
  6. 瀏覽器端 FormData 未設定 enctype="multipart/form-data"

驗證測試指令

# 建立 30MB 測試檔
dd if=/dev/zero of=test_30m.bin bs=1M count=30

# curl 上傳測試
curl -X POST -F "file=@test_30m.bin" https://example.com/upload.php -v
# 觀察:Content-Length、100 Continue、最終回應碼
Copyright © Windows教程網 All Rights Reserved