本文介紹一個採用 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() 方法。
執行完整上傳流程:
is_uploaded_file$allow_ext 白名單iconv('utf-8','gbk',...) 編碼轉換,適配 Windows 伺服器)$allow_sizemove_uploaded_file 移動檔案(同樣進行編碼轉換)$_FILES['error'] 代碼設定詳細錯誤訊息成功回傳 true,失敗回傳 false 並可透過 $error_code 取得錯誤原因。
取得檔案屬性:
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'] 為陣列時)。finfo_file)防止副檔名偽裝。UploadInterface 方便替換實作(如 S3、OSS)。iconv,改用可配置的編碼轉換策略。upload 類別結構清晰、功能完整,特別針對中文 Windows 環境的編碼問題提供了解決方案。其錯誤處理機制詳細,便於除錯。雖然程式碼風格屬於 PHP 5 早期,但核心邏輯仍具參考價值。現代專案建議依上述建議重構,或採用成熟元件(如 symfony/http-foundation 的 UploadedFile、Laravel Storage)以獲得更佳的安全性、擴充性與維護性。