在 Web 開發中,將使用者上傳的圖片直接儲存於資料庫(以 BLOB 型別)是一種常見需求。本文提供一個完整的 PHP + MySQL 範例,涵蓋資料表建立、檔案上傳處理、二進位資料寫入資料庫,以及從資料庫讀取並輸出圖片的完整流程。
首先建立一個資料表 pix,用於儲存圖片標題與二進位資料:
CREATE TABLE `pix` (
`pid` INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
`title` TEXT,
`imgdata` LONGBLOB
);
使用 mysqli 替代已棄用的 mysql 擴展,並啟用錯誤報告:
<?php
$mysqli = new mysqli("localhost", "root", "", "db1");
if ($mysqli->connect_errno) {
die("資料庫連線失敗: " . $mysqli->connect_error);
}
$mysqli->set_charset("utf8mb4");
?>
表單送出後,將暫存檔讀取為二進位字串,經 addslashes 轉義後寫入:
<?php
if (isset($_POST['completed']) && $_POST['completed'] == 1) {
$tmpName = $_FILES['imagefile']['tmp_name'];
$maxSize = 150000; // 150KB
if (is_uploaded_file($tmpName) && filesize($tmpName) <= $maxSize) {
$fp = fopen($tmpName, 'rb');
$imageData = addslashes(fread($fp, filesize($tmpName)));
fclose($fp);
$title = $mysqli->real_escape_string($_POST['whatsit']);
$sql = "INSERT INTO pix (title, imgdata) VALUES ('$title', '$imageData')";
if ($mysqli->query($sql)) {
$msg = "圖片上傳成功!";
} else {
$msg = "資料庫寫入失敗: " . $mysqli->error;
}
} else {
$msg = "檔案過大或上傳失敗,限制 $maxSize 位元組。";
}
}
?>
建立獨立的圖片輸出腳本 show_image.php,透過 pid 參數讀取並送出正確的 HTTP 標頭:
<?php
// show_image.php
require_once 'db_connect.php';
$pid = isset($_GET['pid']) ? (int)$_GET['pid'] : 0;
if ($pid > 0) {
$stmt = $mysqli->prepare("SELECT imgdata FROM pix WHERE pid = ?");
$stmt->bind_param("i", $pid);
$stmt->execute();
$stmt->bind_result($imgData);
if ($stmt->fetch()) {
header("Content-Type: image/jpeg");
echo $imgData;
} else {
header("HTTP/1.0 404 Not Found");
}
$stmt->close();
}
$mysqli->close();
?>
在主頁面中嵌入圖片標籤指向 show_image.php,並提供上傳表單:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>圖片上傳示範</title></head>
<body>
<h2>最新上傳圖片</h2>
<?php if (!empty($msg)) echo "<p style='color:red'>$msg</p>"; ?>
<?php
// 取得最新一筆圖片
$res = $mysqli->query("SELECT pid, title FROM pix ORDER BY pid DESC LIMIT 1");
if ($row = $res->fetch_assoc()) {
echo "<img src='show_image.php?pid={$row['pid']}' alt='' width='200'><br>";
echo "<strong>{$row['title']}</strong>";
} else {
echo "<p>資料庫中尚無圖片</p>";
}
?>
<hr>
<h2>上傳新圖片</h2>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="completed" value="1">
<input type="hidden" name="MAX_FILE_SIZE" value="150000">
選擇圖片: <input type="file" name="imagefile" accept="image/*"><br>
圖片標題: <input type="text" name="whatsit" required><br>
<button type="submit">上傳</button>
</form>
</body>
</html>
utf8mb4。完整程式碼可參考 GitHub 範例專案。