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

PHP 圖片上傳與顯示完整實作:從表單到資料庫

     編輯:程式設計綜合問答

前言

圖片上傳是 Web 應用的基礎功能。本文提供一個完整、安全的 PHP 範例,涵蓋:前端表單、後端驗證、檔案儲存、資料庫記錄路徑、以及前端顯示邏輯。

一、 資料庫準備

CREATE TABLE `images` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `filename` VARCHAR(255) NOT NULL COMMENT '原始檔名',
  `stored_name` VARCHAR(255) NOT NULL COMMENT '伺服器存儲檔名',
  `filepath` VARCHAR(500) NOT NULL COMMENT '相對網站根目錄路徑',
  `mime_type` VARCHAR(50) NOT NULL,
  `filesize` INT UNSIGNED NOT NULL,
  `uploaded_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、 上傳表單

<form action="upload.php" method="post" enctype="multipart/form-data">
  <input type="hidden" name="MAX_FILE_SIZE" value="2097152"> <!-- 2MB -->
  <label>選擇圖片:<input type="file" name="photo" accept="image/*" required></label>
  <button type="submit">上傳</button>
</form>

三、 核心上傳邏輯

<?php
// upload.php
require_once 'db.php'; // PDO 連線

$target_dir = __DIR__ . '/uploads/';
if (!is_dir($target_dir)) mkdir($target_dir, 0755, true);

$allowed_mimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
$max_size = 2 * 1024 * 1024; // 2MB

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['photo'])) {
    $file = $_FILES['photo'];

    // 1. 錯誤檢查
    if ($file['error'] !== UPLOAD_ERR_OK) {
        die('上傳錯誤代碼: ' . $file['error']);
    }

    // 2. MIME 型別驗證(使用 finfo 防偽造)
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime = $finfo->file($file['tmp_name']);
    if (!in_array($mime, $allowed_mimes, true)) {
        die('不支援的檔案類型: ' . $mime);
    }

    // 3. 大小檢查
    if ($file['size'] > $max_size) {
        die('檔案過大,限制 2MB');
    }

    // 4. 產生唯一儲存檔名,防覆蓋與路徑遍歷
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    $stored_name = bin2hex(random_bytes(16)) . '.' . strtolower($ext);
    $dest_path = $target_dir . $stored_name;

    // 5. 移動檔案
    if (!move_uploaded_file($file['tmp_name'], $dest_path)) {
        die('檔案移動失敗,請檢查目錄權限');
    }

    // 6. 寫入資料庫
    $stmt = $pdo->prepare(
        'INSERT INTO images (filename, stored_name, filepath, mime_type, filesize)
         VALUES (?, ?, ?, ?, ?)'
    );
    $relative_path = 'uploads/' . $stored_name;
    $stmt->execute([
        $file['name'],
        $stored_name,
        $relative_path,
        $mime,
        $file['size']
    ]);

    echo '上傳成功!ID: ' . $pdo->lastInsertId();
    exit;
}
?>

四、 圖片顯示頁面

<?php
// gallery.php
require_once 'db.php';
$stmt = $pdo->query('SELECT id, filepath, filename FROM images ORDER BY uploaded_at DESC');
$images = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>圖片庫</title></head>
<body>
<h1>已上傳圖片</h1>
<div style="display:flex; flex-wrap:wrap; gap:16px;">
  <?php foreach ($images as $img): ?>
    <figure style="width:200px; text-align:center;">
      <img src="<?= htmlspecialchars($img['filepath']) ?>" alt="<?= htmlspecialchars($img['filename']) ?>" style="max-width:100%; height:auto;">
      <figcaption><?= htmlspecialchars($img['filename']) ?></figcaption>
    </figure>
  <?php endforeach; ?>
</div>
</body>
</html>

五、 安全性加強清單

  • 檔案型別:務必用 finfo 檢測真實 MIME,勿信任 $_FILES['type']。
  • 執行權限:uploads/ 目錄設定 php_flag engine off 或放在網站根目錄外,防止腳本執行。
  • 檔名處理:使用隨機雜湊檔名,避免中文檔名編碼問題與覆蓋風險。
  • 大小限制:同時設定 php.ini 的 upload_max_filesize、post_max_size 及表單隱藏欄位 MAX_FILE_SIZE。
  • 資料庫:使用預處理語句防 SQL 注入。

結語

以上範例展示了從零建立一個安全、可維護的 PHP 圖片上傳系統的完整流程。實際部署時,建議再加入圖片壓縮、縮圖生成、CDN 整合等進階功能。

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