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

PHP 檔案上傳與相簿管理完整範例:upimage.php 解析

     編輯:PHP 綜合知識

本文展示一個單一檔案 upimage.php 即完成圖片上傳、資訊記錄、相簿顯示與表單呈現的完整相簿系統。程式碼緊湊但包含典型上傳流程所有關鍵步驟,適合作為 PHP 檔案上傳教學案例。

核心流程解析

1. 上傳處理區塊(if ($upload))

if ($picurl == "none") { echo "你沒有上傳任何文件."; exit; }
$v = opendir("image");
if ($v == 0) { mkdir("image"); $v = opendir("image"); }
$up = copy("$picurl", "image/$picurl_name"); // 關鍵:移動暫存檔
if ($up == 1) {
    // 寫入 photo.txt 記錄
    $fp = fopen("photo.txt", "a");
    $mydate = date("Y年m月d日 h:i A");
    $photonote = nl2br($photonote);
    $text = "照片名:<a href='image/$picurl_name' target='_blank'>$picurl_name</a> <br>
             照片大小:$picurl_size byte<br> 照片說明:<BR><span class='blue10'>$photonote</span><br>
             <div align='right'>上傳人: $user($mydate)</div><hr>";
    fwrite($fp, $text, strlen($text));
    fclose($fp);
    unlink($picurl); // 刪除暫存檔
    closedir($v);
}

關鍵變數來源(依賴 register_globals 與 PHP 4 上傳機制)

  • $picurl:暫存檔完整路徑(如 /tmp/phpA1B2C3)
  • $picurl_name:原始檔名
  • $picurl_size:檔案大小(位元組)
  • $picurl_type:MIME 型別(未使用)

現代對應:$_FILES['picurl']['tmp_name']、['name']、['size']、['type']。

2. 相簿顯示區塊

<?php readfile("photo.txt"); ?>

直接輸出純文字記錄檔(含 HTML 標籤),簡單但無分頁、無搜尋、無刪除功能。

3. 上傳表單

<form action="upimage.php" method="post" enctype="multipart/form-data" name="UL">
  <input type="file" name="picurl" size="15" accept="image/x-png,image/gif,image/jpeg">
  <textarea name="photonote" cols="50" rows="5"></textarea>
  <input type="text" name="user" size="10" maxlength="10">
  <input type="Submit" name="upload" value="上傳">
</form>

enctype="multipart/form-data" 是檔案上傳的必要條件,accept 屬性提供客戶端檔案類型過濾(僅 UI 提示,伺服器仍需驗證)。

安全性與功能性缺失分析

問題風險/影響修正建議
直接使用原始檔名 $picurl_name 覆蓋同名檔、路徑遍歷(../../etc/passwd)、特殊字元導致路徑錯誤 重新命名:$newName = uniqid() . '_' . basename($name) 或 UUID + 副檔名
無檔案型別驗證 上傳惡意腳本(.php、.phtml)經 Web 伺服器解析導致 RCE 1. 檢查 MIME $_FILES['picurl']['type'] 2. getimagesize() 驗證圖片 3. 儲存目錄設定 php_flag engine off / AddType text/plain .php
無檔案大小限制 佔滿磁碟、DoS php.ini: upload_max_filesize, post_max_size + 程式碼檢查 $_FILES['picurl']['size']
使用 copy() 而非 move_uploaded_file() 無法確認檔案確實為 HTTP 上傳,理論上可被偽造 必須使用 move_uploaded_file($_FILES['picurl']['tmp_name'], $dest)
記錄檔 photo.txt 直接輸出 XSS:說明欄位注入 <script>alert(1)</script> 將在顯示時執行 htmlspecialchars() 輸出轉義,或改用資料庫儲存結構化資料
目錄建立權限問題 mkdir("image") 預設 0777 受 umask 影響,可能失敗或權限過大 mkdir("image", 0755, true) 遞迴建立並明確權限
併發寫入 photo.txt 無鎖定 多用戶同時上傳導致資料遺失/交錯 改用資料庫(自動行鎖)或 flock() 檔案鎖

現代化架構建議

  1. 資料庫取代文字檔:建立 photos 表(id, filename, original_name, size, mime, description, uploader, ip, created_at),支援分頁、搜尋、刪除、編輯。
  2. 檔案儲存分離:實體檔案存於 storage/app/public/photos/{year}/{month}/{uuid}.ext,資料庫只存相對路徑,配合 php artisan storage:link 或 Nginx X-Accel-Redirect 下載。
  3. 上傳元件化:前端使用 Dropzone.js、Uppy 或 Vue/React 上傳元件,支援拖曳、預覽、進度條、分塊上傳大檔案。
  4. 圖片處理管線:上傳後自動生成縮圖(Intervention Image、Imagine)、WebP 轉換、EXIF 剝離、病毒掃描(ClamAV)。
  5. 權限控管:登入驗證、CSRF Token、上傳頻率限制(Rate Limiting)、內容審核佇列。
此單檔案範例雖簡陋,但完整呈現了「接收 → 驗證 → 移動 → 記錄 → 顯示」的上傳核心流程。現代開發應將各環節模組化、服務化,並以安全性優先原則設計每一層防禦。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved