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

PHP 檔案上傳類別:支援縮圖、浮水印、多檔、自訂目錄完整實作

     編輯:PHP 相關知識

類別特色

upload 類別封裝完整上傳流程:檔案類型/大小驗證、日期分層目錄自動建立、多檔上傳、等比縮圖、圖片浮水印(支援透明度/位置)、回傳結構化結果。採用屬性設定模式,靈活組合功能。

核心類別程式碼(節錄關鍵方法)

class upload {
    var $dir, $time, $allow_types, $field, $maxsize;
    var $thumb_width, $thumb_height;
    var $watermark_file, $watermark_pos, $watermark_trans;

    function __construct($types = 'jpg|png', $maxsize = 1024, $field = 'attach', $time = '') {
        $this->allow_types = explode('|', $types);
        $this->maxsize = $maxsize * 1024; // KB → Bytes
        $this->field = $field;
        $this->time = $time ? $time : time();
    }

    // 設定儲存目錄:支援 {y}{m}{d} 日期佔位符
    function set_dir($basedir, $filedir = '') {
        $dir = $basedir;
        !is_dir($dir) && @mkdir($dir, 0777);
        if (!empty($filedir)) {
            $filedir = str_replace(array('{y}','{m}','{d}'), array(date('Y',$this->time), date('m',$this->time), date('d',$this->time)), strtolower($filedir));
            foreach (explode('/',$filedir) as $d) {
                !empty($d) && $dir .= $d.'/';
                !is_dir($dir) && @mkdir($dir, 0777);
            }
        }
        $this->dir = $dir;
    }

    // 執行上傳主流程
    function execute() {
        $files = array();
        $keys = array_keys($_FILES[$this->field]['name']);
        foreach ($keys as $key) {
            if (!$_FILES[$this->field]['name'][$key]) continue;
            
            $fileext = $this->fileext($_FILES[$this->field]['name'][$key]);
            $filename = date('Ymdhis', $this->time) . mt_rand(10,99) . '.' . $fileext;
            $filedir = $this->dir;
            $filesize = $_FILES[$this->field]['size'][$key];

            // 驗證類型與大小
            if (!in_array($fileext, $this->allow_types)) { $files[$key] = array('name'=>$_FILES[$this->field]['name'][$key], 'flag'=>-1); continue; }
            if ($filesize > $this->maxsize) { $files[$key] = array('name'=>$_FILES[$this->field]['name'][$key], 'size'=>$filesize, 'flag'=>-2); continue; }

            $files[$key] = array('name'=>$filename, 'dir'=>$filedir, 'size'=>$filesize);

            // 移動檔案
            if (is_uploaded_file($_FILES[$this->field]['tmp_name'][$key])) {
                move_uploaded_file($_FILES[$this->field]['tmp_name'][$key], $filedir.$filename);
                @unlink($_FILES[$this->field]['tmp_name'][$key]);
                $files[$key]['flag'] = 1;

                // 圖片後處理
                if (in_array($fileext, array('jpg','png'))) {
                    if ($this->thumb_width) {
                        if ($this->create_thumb($filedir.$filename, $filedir.'thumb_'.$filename)) {
                            $files[$key]['thumb'] = 'thumb_'.$filename;
                        }
                    }
                    $this->create_watermark($filedir.$filename);
                }
            }
        }
        return $files;
    }

    // 等比縮圖(支援 jpg/png/gif)
    function create_thumb($src_file, $thumb_file) {
        // ... 完整程式碼見原文,關鍵點:
        // 1. 來源圖小於目標尺寸直接複製
        // 2. 依長邊比例計算縮放
        // 3. 優先 imagecopyresampled,退而求其次 imagecopyresized
        // 4. 依副檔名呼叫對應輸出函式
    }

    // 圖片浮水印(疊加 PNG/GIF/JPG 水印圖)
    function create_watermark($file) {
        // ... 完整程式碼見原文,關鍵點:
        // 1. 檢查 GD 支援格式與檔案存在
        // 2. 圖片尺寸檢查(背景需大於水印)
        // 3. 9 種位置模式(四角、四邊中、置中、隨機)
        // 4. imageCopyMerge 支援透明度合成
        // 5. 覆蓋原檔輸出
    }

    function fileext($filename) {
        return strtolower(substr(strrchr($filename,'.'), 1, 10));
    }
}

使用範例

set_dir(dirname(__FILE__).'/upload/', '{y}/{m}'); // 基礎目錄 + 年/月子目錄
    $up->set_thumb(100, 80); // 縮圖最大 100x80
    $up->set_watermark(dirname(__FILE__).'/watermark.png', 6, 90); // 水印檔、右下角、90% 不透明
    $fs = $up->execute();
    var_dump($fs);
}
?>




回傳結果結構

Array
(
    [0] => Array
        (
            [name] => 20240115143025_45.jpg    // 伺服器檔名
            [dir] => /var/www/upload/2024/01/  // 實體路徑
            [size] => 102456                   // 位元組
            [flag] => 1                        // 1=成功, -1=類型錯誤, -2=超過大小
            [thumb] => thumb_20240115143025_45.jpg // 縮圖檔名(若啟用)
        )
    // ... 多檔案依序
)

安全性與擴充建議

  1. MIME 偵測:搭配 finfo_file() 驗證真實類型,防副檔名偽裝
  2. 檔名隨機化:現行 日期+隨機數 可改用 uniqid('', true) 或 hash('sha256', ...)
  3. 圖片重繪驗證:上傳後以 imagecreatefromstring() 重讀並儲存,清除潛在惡意代碼
  4. 儲存分離:生產環境建議儲存至非公開目錄或雲端儲存(S3/OSS),透過簽名 URL 存取
  5. 例外處理:將錯誤代碼改為拋出異常,便於上層統一處理
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved