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

PHP 文件上傳完整指南:從 HTML 表單到安全存儲的最佳實踐

     編輯:PHP 相關知識

整體架構

文件上傳包含兩部分:前端 HTML 表單 讓用戶選擇文件,後端 PHP 腳本 接收、驗證、移動文件至永久目錄。

前端表單關鍵點

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="img" />
    <input type="submit" name="submit" value="上傳" />
</form>
  • enctype="multipart/form-data":必須,否則 $_FILES 為空。
  • type="file":瀏覽器顯示文件選擇框。

後端核心代碼

<?php
$DST_DIR = '/data/upload/'; // 需寫入權限

if (!empty($_FILES['img']['name'])) {
    if ($_FILES['img']['error'] > 0) {
        die("上傳失敗,錯誤碼: {$_FILES['img']['error']}");
    }
    $src = $_FILES['img']['tmp_name'];
    $dst = $DST_DIR . basename($_FILES['img']['name']);
    if (move_uploaded_file($src, $dst)) {
        echo "上傳成功:$dst";
    } else {
        echo "移動文件失敗,請檢查目錄權限";
    }
} else {
    echo "請選擇文件";
}

$_FILES 陣列詳解

鍵名說明
name客戶端原始文件名
typeMIME 類型 (瀏覽器提供,不可信)
size文件大小 (位元組)
tmp_name伺服器臨時儲存路徑
error錯誤碼 (0=成功,1=超過 php.ini upload_max_filesize,2=超過表單 MAX_FILE_SIZE,3=部分上傳,4=無文件,6=無臨時目錄,7=寫入失敗)

為何用 move_uploaded_file() 而非 copy()?

move_uploaded_file() 內建檢查文件是否真經由 HTTP POST 上傳,防止惡意腳本利用 copy() 讀取任意伺服器文件 (如 /etc/passwd)。這是安全基線,請務必使用。

安全檢查清單 (生產環境必做)

  1. 副檔名白名單:$ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); in_array($ext, ['jpg','png','gif','pdf'])
  2. MIME 類型二次驗證:finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tmp) 對比白名單。
  3. 文件大小限制:$_FILES['img']['size'] <= 2 * 1024 * 1024 (2MB)。
  4. 重命名存儲:$newName = uniqid() . '.' . $ext; 避免覆蓋、路徑遍歷。
  5. 存放於 Web 根目錄外 或配置 Nginx/Apache 禁止腳本執行。
  6. 圖片二次渲染:imagecreatefromstring(file_get_contents($tmp)) 再存,剝離潛在惡意代碼。

常見 php.ini 設定

file_uploads = On
upload_max_filesize = 8M
post_max_size = 10M          ; 必須 > upload_max_filesize
max_file_uploads = 20
upload_tmp_dir = /tmp/php_upload

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

大文件建議採用 Plupload、Uppy 等前端庫配合 PHP 分塊合併,超出本文範圍,請參考專門教程。

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