將圖片、PDF 等二進位檔案直接存入 MySQL 資料庫(而非僅存路徑)在特定場景下具備優勢:資料完整性強、備份單一化、權限控管集中。本文示範如何建立資料表、透過 HTML 表單上傳、以及以 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,
filename CHAR(50),
filesize CHAR(50),
filetype CHAR(50)
);
欄位說明: LONGBLOB 可儲存最多 4GB 二進位資料;filetype 儲存 MIME 類型(如 image/jpeg),供瀏覽器正確渲染。
store.php<?php
// store.php - 儲存二進位檔案至 MySQL
$host = 'localhost'; $user = 'root'; $pass = 'password'; $db = 'binary_data';
if (isset($_POST['submit'])) {
$conn = mysqli_connect($host, $user, $pass, $db);
if (!$conn) die('連線失敗: ' . mysqli_connect_error());
$desc = mysqli_real_escape_string($conn, $_POST['form_description']);
$file = $_FILES['form_data'];
$data = addslashes(file_get_contents($file['tmp_name']));
$name = mysqli_real_escape_string($conn, $file['name']);
$size = $file['size'];
$type = mysqli_real_escape_string($conn, $file['type']);
$sql = "INSERT INTO binary_data (description, bin_data, filename, filesize, filetype)
VALUES ('$desc', '$data', '$name', '$size', '$type')";
if (mysqli_query($conn, $sql)) {
$id = mysqli_insert_id($conn);
echo "檔案已儲存,資料庫 ID: $id(請記下此 ID 供後續讀取)";
} else {
echo "錯誤: " . mysqli_error($conn);
}
mysqli_close($conn);
} else {
?>
上傳檔案至資料庫
<?php } ?>
關鍵點:表單必須設 enctype="multipart/form-data";使用 $_FILES 陣列取得暫存檔路徑 tmp_name;addslashes() 處理二進位資料中的特殊字元(現代建議改用 mysqli_real_escape_string 或預處理語句)。
getdata.php<?php
// getdata.php - 依 ID 輸出二進位內容
$host = 'localhost'; $user = 'root'; $pass = 'password'; $db = 'binary_data';
if (isset($_GET['id']) && ctype_digit($_GET['id'])) {
$id = (int)$_GET['id'];
$conn = mysqli_connect($host, $user, $pass, $db);
if (!$conn) die('連線失敗');
$sql = "SELECT bin_data, filetype FROM binary_data WHERE id = $id";
$res = mysqli_query($conn, $sql);
if ($row = mysqli_fetch_assoc($res)) {
header("Content-Type: " . $row['filetype']);
echo $row['bin_data'];
} else {
header("HTTP/1.0 404 Not Found");
echo "找不到指定 ID 的檔案";
}
mysqli_close($conn);
} else {
echo "請提供有效的 id 參數,例如:getdata.php?id=3";
}
?>
<!-- 直接當作圖片來源 -->
<img src="getdata.php?id=3" alt="資料庫圖片">
<!-- 或提供下載連結 -->
<a href="getdata.php?id=5">下載檔案 (ID=5)</a>
預設 PHP 與 MySQL 多項設定限制上傳大小,需同步調整:
| 層面 | 設定項目 | 建議值 (24MB) |
|---|---|---|
| HTML 表單 | <input type="hidden" name="MAX_FILE_SIZE" value="24000000"> | 24000000 |
| PHP (php.ini) | upload_max_filesize | 24M |
| PHP (php.ini) | post_max_size | 32M (略大於 upload_max_filesize) |
| PHP (php.ini) | memory_limit | 64M 以上 |
| MySQL 啟動參數 | max_allowed_packet | 24M |
MySQL 啟動範例:
/usr/local/bin/mysqld_safe --max_allowed_packet=24M --key_buffer=16M --table_cache=128 --sort_buffer=4M --record_buffer=1M &
注意:資料庫儲存大量二進位資料會導致備份檔案極大、記憶體壓力增加,生產環境建議評估「儲存檔案路徑 + 物件儲存(S3/MinIO)」架構。
mysqli_prepare / PDO::prepare)替代字串拼接。$_FILES['type'],建議用 finfo_file() 偵測真實 MIME。INSERT、SELECT),避免使用 root 直連。bin_data 拆分至獨立資料表甚至獨立資料庫實例。透過本文完整範例,您可以快速建立「資料庫即檔案儲存」的原型系統,並理解相關參數調校與安全性要點,為後續架構決策提供實證依據。