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

PHP 上傳大文件導致 $_FILES 為空的根因與解決方案

     編輯:PHP 相關知識

現象

上傳 4.66MB 的 GIF 圖片,$_FILES['file']['size'] 為 0,$_FILES['file']['error'] 為 1(UPLOAD_ERR_INI_SIZE),小文件正常。

根因分析

php.ini 中 upload_max_filesize = 2M 導致 PHP 直接拒絕接收超大文件,$_FILES 雖存在但內容為空/錯誤碼。

解決步驟

1. 修改 php.ini(核心)

; 文件上傳核心配置
file_uploads = On
upload_max_filesize = 50M        ; 單文件上限
post_max_size = 60M              ; 必須 > upload_max_filesize
memory_limit = 128M              ; 建議 ≥ post_max_size
max_execution_time = 300         ; 大文件需更長執行時間
max_input_time = 300             ; 解析輸入數據時間
upload_tmp_dir = /var/www/tmp    ; 確保目錄存在且 www-data 可寫

2. 重啟 PHP-FPM 生效

# systemd 系統
sudo systemctl restart php8.1-fpm

# 或發送信號
sudo kill -USR2 $(cat /run/php/php8.1-fpm.pid)

3. Nginx 同步調整(關鍵)

# nginx.conf http 段或 server 段
client_max_body_size 60M;  # 默認 1M,必須 ≥ post_max_size

# 重載
nginx -s reload

4. 表單必要屬性

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">上傳</button>
</form>

驗證配置生效

<?php
// test_upload.php
echo "upload_max_filesize: " . ini_get('upload_max_filesize') . "\n";
echo "post_max_size: " . ini_get('post_max_size') . "\n";
echo "memory_limit: " . ini_get('memory_limit') . "\n";
echo "file_uploads: " . (ini_get('file_uploads') ? 'On' : 'Off') . "\n";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    var_dump($_FILES);
}
?>

常見遺漏檢查清單

項目檢查點
php.ini 路徑php --ini 確認載入的文件
多版本 PHPCLI 和 FPM 可能用不同 ini
單位後綴M/K/G 不區分大小寫,無單位視為字節
post_max_size < upload_max_filesize導致 POST 數據被截斷,$_FILES 為空
Nginx/Apache 限制client_max_body_size / LimitRequestBody
臨時目錄權限chown www-data:www-data /var/www/tmp
磁盤空間df -h 確認臨時分區有空間
安全模式/損壞檢查open_basedir 限制臨時目錄訪問

進階:分片上傳突破限制

若業務需上傳 GB 級文件,單純調大配置不可行,需前端分片 + 後端合併:

<?php
// 後端合併分片示例
$chunkDir = '/var/www/uploads/chunks/' . $fileId;
$finalPath = '/var/www/uploads/' . $fileName;

$chunks = glob($chunkDir . '/part_*');
sort($chunks, SORT_NATURAL);

$fp = fopen($finalPath, 'wb');
foreach ($chunks as $chunk) {
    fwrite($fp, file_get_contents($chunk));
    unlink($chunk); // 刪除分片
}
fclose($fp);
rmdir($chunkDir);
?>

總結

  1. 核心配置:upload_max_filesize + post_max_size(php.ini)
  2. Web 服務器同步:client_max_body_size (Nginx) / LimitRequestBody (Apache)
  3. 重啟服務生效
  4. 驗證 ini_get() 確認生效
  5. 超大文件採用分片上傳架構

配置鏈路中任一環節受限,都會導致上傳失敗,系統性排查是關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved