本文演示如何將圖片、HTML 等二進制文件直接存入 MySQL 數據庫,包含建表、上傳存儲、讀取輸出的完整 PHP 代碼實現。
CREATE DATABASE binary_data;
USE binary_data;
CREATE TABLE binary_data (
id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
description CHAR(50),
bin_data LONGBLOB, -- 核心:存儲二進制內容(最大 4GB)
filename CHAR(50),
filesize CHAR(50),
filetype CHAR(50)
);
類型選擇:TINYBLOB (255B)、BLOB (64KB)、MEDIUMBLOB (16MB)、LONGBLOB (4GB)。圖片建議 MEDIUMBLOB 或 LONGBLOB。
<?php
// store.php
if (isset($_POST['submit'])) {
// 1. 連接數據庫
$conn = mysqli_connect("localhost", "root", "password", "binary_data");
// 2. 讀取並轉義二進制數據
$fileTmp = $_FILES['form_data']['tmp_name'];
$data = mysqli_real_escape_string($conn, file_get_contents($fileTmp));
// 3. 獲取文件元信息
$desc = $_POST['form_description'];
$fname = $_FILES['form_data']['name'];
$fsize = $_FILES['form_data']['size'];
$ftype = $_FILES['form_data']['type'];
// 4. 插入數據庫
$sql = "INSERT INTO binary_data (description, bin_data, filename, filesize, filetype)
VALUES ('$desc', '$data', '$fname', '$fsize', '$ftype')";
mysqli_query($conn, $sql);
$id = mysqli_insert_id($conn);
echo "文件存儲成功,數據庫 ID: $id
";
mysqli_close($conn);
} else {
?>
<form method="post" enctype="multipart/form-data">
文件描述: <input type="text" name="form_description" size="40"><br>
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
選擇文件: <input type="file" name="form_data" size="40"><br>
<input type="submit" name="submit" value="上傳存儲">
</form>
<?php } ?>
<?php
// getdata.php?id=123
$id = (int)$_GET['id'];
$conn = mysqli_connect("localhost", "root", "password", "binary_data");
$sql = "SELECT bin_data, filetype, filename FROM binary_data WHERE id=$id";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_assoc($result);
if ($row) {
// 關鍵:發送正確 MIME 頭
header("Content-Type: " . $row['filetype']);
header("Content-Disposition: inline; filename=\"" . $row['filename'] . "\"");
echo $row['bin_data'];
} else {
header("HTTP/1.0 404 Not Found");
echo "文件不存在";
}
mysqli_close($conn);
?>
| 環節 | 關鍵點 |
|---|---|
| 上傳表單 | enctype="multipart/form-data" + MAX_FILE_SIZE 隱藏域 |
| 二進制轉義 | mysqli_real_escape_string() 防止 SQL 語法破壞(或用 PreparedStatement) |
| 大文件處理 | PHP upload_max_filesize/post_max_size / MySQL max_allowed_packet 三方同步調大 |
| 輸出瀏覽器 | header('Content-Type: ...') 必須在任何輸出前發送 |
| 性能考量 | 頻繁讀寫大 BLOB 會衝擊緩存池,高併發建議「存文件系統+庫存路徑」 |