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

PHP 實用檔案上傳類 upload 完整解析

     編輯:PHP 相關知識

前言

本文介紹一個採用 PHP 5 物件導向風格撰寫的檔案上傳類別 upload,支援檔案類型白名單、大小限制、目錄權限檢查、覆蓋控制、自訂檔名、編碼轉換(UTF-8 轉 GBK)等實用功能,適合中文環境專案直接使用。

類別屬性速覽

class upload {
    var $file_field = 'file';        // $_FILES 鍵名
    var $file_array;                 // $_FILES[$file_field] 內容
    var $save_path = '';             // 儲存目錄
    var $define_name;                // 自訂檔名(不含副檔名)
    var $name;                       // 最終檔名
    var $size;                       // 檔案大小
    var $ext;                        // 副檔名
    var $allow_ext = array();        // 允許副檔名陣列
    var $allow_size = false;         // 最大位元組,false=不限制
    var $overwrite = false;          // 是否覆蓋同名檔案
    var $error_code;                 // 錯誤訊息
}

建構子:自動初始化與驗證

public function __construct() {
    if (!is_uploaded_file($_FILES[$this->file_field]['tmp_name'])) {
        die("非法上傳!");
    } else {
        $this->file_array = $_FILES[$this->file_field];
        $this->name = $this->getpro('name');
        $this->size = $this->getpro('size');
        $this->ext  = $this->getpro('ext');
    }
}

建構子會立即檢查是否為合法上傳檔案,並提取檔名、大小、副檔名。若需延後處理,建議改為分離的 init() 方法。

核心方法:upload()

執行完整上傳流程:

  1. 再次確認 is_uploaded_file
  2. 驗證副檔名是否在 $allow_ext 白名單
  3. 檢查目錄存在與可寫(含 iconv('utf-8','gbk',...) 編碼轉換,適配 Windows 伺服器)
  4. 檢查同名檔案與覆蓋設定
  5. 驗證檔案大小 $allow_size
  6. 呼叫 move_uploaded_file 移動檔案(同樣進行編碼轉換)
  7. 失敗時根據 $_FILES['error'] 代碼設定詳細錯誤訊息

成功回傳 true,失敗回傳 false 並可透過 $error_code 取得錯誤原因。

輔助方法:getpro($item)

取得檔案屬性:

  • name:若設定 $define_name 則回傳「自訂名.副檔名」,否則回傳原始檔名
  • ext:解析並回傳小寫副檔名
  • size:回傳檔案大小

使用範例

<form action="do_upload.php" method="post" enctype="multipart/form-data">
  <input type="file" name="myfile">
  <input type="submit" value="上傳">
</form>

<?php
// do_upload.php
require_once 'upload.class.php';

$up = new upload();
// 設定屬性
$up->file_field = 'myfile';           // 對應 input name
$up->save_path  = './uploads/';       // 儲存目錄
$up->allow_ext  = array('jpg', 'png', 'gif', 'pdf');
$up->allow_size = 2 * 1024 * 1024;    // 2MB
$up->overwrite  = false;
$up->define_name = 'custom_name';     // 選填:自訂檔名

if ($up->upload()) {
    echo "上傳成功!檔名:{$up->name}";
} else {
    echo "上傳失敗:" . $up->error_code;
}
?>

編碼轉換說明

類別中多處使用 iconv('utf-8','gbk', $path),主要解決 Windows 伺服器檔案系統預設使用 GBK 編碼,而 PHP 腳本為 UTF-8 導致的中文檔名亂碼/找不到檔案問題。若伺服器為 Linux(檔案系統通常為 UTF-8),可移除此轉換或加入環境判斷。

錯誤代碼對照表

$_FILES['error']錯誤訊息
1上傳的檔案超過了 upload_max_filesize 選項限制的值!
2上傳檔案的大小超過了 HTML 表單中 max_file_size 選項指定的值!
3上傳過程被中斷!
4沒有檔案被上傳!
6找不到臨時檔案夾!
7檔案寫入失敗!

改進建議

  • 將 var 改為 public/private/protected,加入型別提示(PHP 7.4+)。
  • 建構子不應直接 die(),改拋出例外或回傳狀態,由呼叫端決定處理方式。
  • 支援多檔上傳($_FILES[$field]['name'] 為陣列時)。
  • 新增 MIME 類型驗證(finfo_file)防止副檔名偽裝。
  • 提供介面 UploadInterface 方便替換實作(如 S3、OSS)。
  • 移除硬編碼的 iconv,改用可配置的編碼轉換策略。

總結

upload 類別結構清晰、功能完整,特別針對中文 Windows 環境的編碼問題提供了解決方案。其錯誤處理機制詳細,便於除錯。雖然程式碼風格屬於 PHP 5 早期,但核心邏輯仍具參考價值。現代專案建議依上述建議重構,或採用成熟元件(如 symfony/http-foundation 的 UploadedFile、Laravel Storage)以獲得更佳的安全性、擴充性與維護性。

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