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

PHP 檔案上傳完整實作:單檔、多檔、圖片水印、縮圖預覽

     編輯:PHP 綜合知識

檔案上傳是 Web 系統核心功能。本文提供可直接落地的完整範例,涵蓋單檔/多檔上傳、型別/大小驗證、GD 圖片水印、縮圖預覽、IFrame 無刷新上傳。

核心流程圖

  1. 前端 <form enctype="multipart/form-data"> + <input type="file" name="upfile[]" multiple>
  2. PHP $_FILES['upfile'] 取得陣列結構
  3. 驗證 error、size、type、副檔名
  4. move_uploaded_file() 移至永久目錄
  5. (選擇)GD 處理水印、縮圖
  6. 回傳 JSON 或導向結果頁

後端完整程式碼(submit_form_process.php)

<?php
// 設定區
$uptypes = ['image/jpg','image/jpeg','image/png','image/pjpeg','image/gif','image/bmp','image/x-png'];
$max_file_size = 2 * 1024 * 1024; // 2MB
$destination_folder = __DIR__ . '/uploads/';
$watermark = 1;        // 1=加水印
$watertype = 1;        // 1=文字 2=圖片
$waterposition = 1;    // 1=左下 2=右下 3=左上 4=右上 5=置中
$waterstring = 'Demo'; // 水印文字
$waterimg = 'logo.png'; // 水印圖片
$imgpreview = 1;       // 產生縮圖
$imgpreviewsize = 0.5; // 縮圖比例

if ($_SERVER['REQUEST_METHOD'] !== 'POST') exit('Invalid request');

$files = $_FILES['upfile'];
// 多檔結構正規化:['name'=>[], 'type'=>[], 'tmp_name'=>[], 'error'=>[], 'size'=>[]]
$count = count($files['name']);
for ($i = 0; $i < $count; $i++) {
    $file = [
        'name'     => $files['name'][$i],
        'type'     => $files['type'][$i],
        'tmp_name' => $files['tmp_name'][$i],
        'error'    => $files['error'][$i],
        'size'     => $files['size'][$i],
    ];
    process_upload($file);
}

function process_upload($file) {
    global $uptypes, $max_file_size, $destination_folder, $watermark, $watertype, $waterposition, $waterstring, $waterimg, $imgpreview, $imgpreviewsize;

    if ($file['error'] !== UPLOAD_ERR_OK) { echo "錯誤代碼:{$file['error']}<br>"; return; }
    if ($file['size'] > $max_file_size) { echo "檔案過大<br>"; return; }
    if (!in_array($file['type'], $uptypes)) { echo "型別不允許:{$file['type']}<br>"; return; }

    if (!is_dir($destination_folder)) mkdir($destination_folder, 0755, true);

    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    $newName = time() . '_' . mt_rand(1000,9999) . ".$ext";
    $destPath = $destination_folder . $newName;

    if (!move_uploaded_file($file['tmp_name'], $destPath)) { echo "移動失敗<br>"; return; }

    // 圖片後處理
    if ($watermark && in_array($file['type'], ['image/jpg','image/jpeg','image/png','image/gif'])) {
        add_watermark($destPath, $file['type']);
    }
    if ($imgpreview) {
        create_thumb($destPath, $file['type'], $imgpreviewsize);
    }

    echo "<font color=green>上傳成功</font>:$newName <br>";
}

// 水印與縮圖函數略(使用 GD imagecopy、imagecopyresampled)
?>

前端表單(支援多檔 + IFrame 無刷新)

<!-- 一般提交 -->
<form action="submit_form_process.php" method="post" enctype="multipart/form-data">
  <input type="file" name="upfile[]" multiple>
  <input type="submit" value="上傳">
</form>

<!-- IFrame 無刷新 -->
<iframe name="uploadFrame" style="display:none"></iframe>
<form action="submit_form_process.php" method="post" enctype="multipart/form-data" target="uploadFrame">
  <input type="file" name="upfile[]" multiple>
  <input type="submit" value="上傳(無刷新)">
</form>

關鍵細節總結

  • name="upfile[]":中括號讓 PHP 接收陣列,否則多檔會互相覆蓋只留最後一個。
  • 型別驗證不可信任 $_FILES['type']:客戶端可偽造,建議配合 finfo_file() 或 getimagesize() 二次驗證。
  • 檔名安全:使用時間戳+隨機數重命名,避免同名覆蓋與路徑遍歷攻擊。
  • 目錄權限:上傳目錄不可執行 PHP(Nginx/Apache 設定 php_flag engine off)。
  • 大檔上傳:調整 upload_max_filesize、post_max_size、max_execution_time、Nginx client_max_body_size。

進階:分片上傳與斷點續傳

大檔(>100MB)建議前端切片(如 WebUploader、Uppy),後端合併分片,支援暫停續傳、秒傳(MD5 秒傳)。

掌握上傳全流程與安全細節,能構建穩健、易維護的檔案管理模組。

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