本文提供一個功能完整的 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('警告:未知錯誤!');
}
}
}
}
?>
<?php
class Tool {
// 彈窗提示並返回上一頁
static public function alertBack($_info) {
echo "";
exit();
}
// 彈窗提示、賦值給 opener 並關閉視窗
static public function alertOpenerClose($_info, $_path) {
echo "";
echo "";
echo "";
echo "";
echo "";
exit();
}
}
?>
<!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>
<!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>
<?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()、檔案魔術位元組檢查)php_flag engine off)