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

PHP 檔案上傳類完整實作與應用範例

     編輯:PHP 綜合知識

PHP 檔案上傳類實作教學

本文提供一個功能完整的 PHP 檔案上傳類,支援圖片類型驗證、自動建立日期目錄、檔案重命名、錯誤處理等功能,並包含完整的前後端整合範例。

核心類別:FileUpload.class.php

<?php
class FileUpload {
    private $error;       // 錯誤代碼
    private $maxsize;     // 最大允許大小(KB)
    private $type;        // MIME 類型
    private $typeArr = array(
        'image/jpeg', 'image/pjpeg', 'image/png', 
        'image/x-png', 'image/gif'
    );
    private $path;        // 絕對儲存路徑
    private $today;       // 今日目錄絕對路徑
    private $name;        // 原始檔名
    private $tmp;         // 暫存檔路徑
    private $linkpath;    // 相對連結路徑
    private $linktotay;   // 今日目錄相對路徑

    public function __construct($_file, $_maxsize) {
        $this->error = $_FILES[$_file]['error'];
        $this->maxsize = $_maxsize / 1024; // 轉換為 KB
        $this->type = $_FILES[$_file]['type'];
        $this->path = ROOT_PATH . UPDIR;
        $this->linktotay = date('Ymd') . '/';
        $this->today = $this->path . $this->linktotay;
        $this->name = $_FILES[$_file]['name'];
        $this->tmp = $_FILES[$_file]['tmp_name'];
        
        $this->checkError();
        $this->checkType();
        $this->checkPath();
        $this->moveUpload();
    }

    // 取得可存取的相對路徑
    public function getPath() {
        $_path = $_SERVER["SCRIPT_NAME"];
        $_dir = dirname(dirname($_path));
        if ($_dir == '\\') $_dir = '/';
        $this->linkpath = $_dir . $this->linkpath;
        return $this->linkpath;
    }

    // 移動上傳檔案
    private function moveUpload() {
        if (is_uploaded_file($this->tmp)) {
            if (!move_uploaded_file($this->tmp, $this->setNewName())) {
                Tool::alertBack('警告:上傳失敗!');
            }
        } else {
            Tool::alertBack('警告:暫存檔不存在!');
        }
    }

    // 生成新檔名:時間戳 + 隨機數 + 原副檔名
    private function setNewName() {
        $_nameArr = explode('.', $this->name);
        $_postfix = $_nameArr[count($_nameArr) - 1];
        $_newname = date('YmdHis') . mt_rand(100, 1000) . '.' . $_postfix;
        $this->linkpath = UPDIR . $this->linktotay . $_newname;
        return $this->today . $_newname;
    }

    // 驗證並建立目錄
    private function checkPath() {
        if (!is_dir($this->path) || !is_writable($this->path)) {
            if (!mkdir($this->path, 0755, true)) {
                Tool::alertBack('警告:主目錄建立失敗!');
            }
        }
        if (!is_dir($this->today) || !is_writable($this->today)) {
            if (!mkdir($this->today, 0755, true)) {
                Tool::alertBack('警告:子目錄建立失敗!');
            }
        }
    }

    // 驗證檔案類型
    private function checkType() {
        if (!in_array($this->type, $this->typeArr)) {
            Tool::alertBack('警告:不合法的上傳類型!');
        }
    }

    // 驗證上傳錯誤
    private function checkError() {
        if (!empty($this->error)) {
            switch ($this->error) {
                case 1: Tool::alertBack('警告:上傳檔案超過 php.ini 限制!'); break;
                case 2: Tool::alertBack('警告:上傳檔案超過表單限制 ' . $this->maxsize . 'KB!'); break;
                case 3: Tool::alertBack('警告:檔案僅部分上傳!'); break;
                case 4: Tool::alertBack('警告:未選擇檔案!'); break;
                default: Tool::alertBack('警告:未知錯誤!');
            }
        }
    }
}
?>

工具類:Tool.class.php

<?php
class Tool {
    // 彈窗提示並返回上一頁
    static public function alertBack($_info) {
        echo "";
        exit();
    }

    // 彈窗提示、賦值給 opener 並關閉視窗
    static public function alertOpenerClose($_info, $_path) {
        echo "";
        echo "";
        echo "";
        echo "";
        echo "";
        exit();
    }
}
?>

前端整合範例

1. 主頁面:index.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>檔案上傳範例</title>
    <script>
    function centerWindow(url, name, width, height) {
        var left = (screen.width - width) / 2;
        var top = (screen.height - height) / 2;
        window.open(url, name, 'width=' + width + ',height=' + height + ',left=' + left + ',top=' + top);
    }
    </script>
</head>
<body>
    <form name="content" method="post" action="?action=add">
        <input type="text" name="thumbnail" class="text" readonly />
        <input type="button" value="上傳圖片" onclick="centerWindow('upfile.html','upfile','400','100')" />
        <img name="pic" style="display:none;" />
        <br />* 僅支援 jpg、gif、png,且不超過 200KB
    </form>
</body>
</html>

2. 上傳彈窗:upfile.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>上傳圖片</title>
</head>
<body>
    <form method="post" action="./upload.php" enctype="multipart/form-data" style="text-align:center;margin:30px;">
        <input type="hidden" name="MAX_FILE_SIZE" value="204800" />
        <input type="file" name="pic" accept="image/*" />
        <input type="submit" name="send" value="確定上傳" />
    </form>
</body>
</html>

3. 處理上傳:upload.php

<?php
require 'FileUpload.class.php';
require 'Tool.class.php';

if (isset($_POST['send'])) {
    $_fileupload = new FileUpload('pic', $_POST['MAX_FILE_SIZE']);
    $_path = $_fileupload->getPath();
    Tool::alertOpenerClose('檔案上傳成功!', $_path);
} else {
    Tool::alertBack('警告:檔案過大或其他未知錯誤!');
}
?>

配置常數(建議放入共用配置檔)

<?php
define('ROOT_PATH', dirname(__FILE__)); // 網站根目錄
define('UPDIR', '/uploads/');           // 上傳主目錄
?>

功能特點總結

功能說明
類型驗證限制為 JPEG、PNG、GIF 等常見圖片格式
大小限制支援 php.ini、表單隱藏欄位、類別建構子三層檢查
目錄管理自動建立 年月日 目錄結構,支援權限檢查
檔名重組時間戳 + 隨機數避免衝突,保留原副檔名
錯誤處理完整覆蓋 UPLOAD_ERR_* 常見錯誤代碼
跨視窗回傳透過 JavaScript 操作 opener 實現無刷新回填

安全性建議

  • 生產環境務必加入檔案內容驗證(如 getimagesize()、檔案魔術位元組檢查)
  • 上傳目錄設定為不可執行腳本(Nginx/Apache 設定 php_flag engine off)
  • 考慮使用雲端儲存(AWS S3、阿里雲 OSS)替代本地儲存
  • 實作上傳頻率限制防止濫用
  • 定期掃描清理異常檔案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved