將上傳檔案以 BLOB 直接存入資料庫,適用於小型檔案、需交易一致性、防止檔案散落的場景。大檔案建議存檔案系統,資料庫只存路徑。
CREATE TABLE updfiles (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(80) NOT NULL,
type VARCHAR(80) NOT NULL,
size INT NOT NULL,
content BLOB,
PRIMARY KEY (id)
);
<?php
$con = mysqli_connect("localhost", "user", "pass", "db");
if (!$con) die("連線失敗: " . mysqli_connect_error());
$err = $_FILES['w3img']['error'];
$tmp = $_FILES['w3img']['tmp_name'];
$size = $_FILES['w3img']['size'];
$name = $_FILES['w3img']['name'];
$type = $_FILES['w3img']['type'];
if ($err === UPLOAD_ERR_OK && $size > 0) {
$fp = fopen($tmp, 'rb');
$content = fread($fp, $size);
fclose($fp);
$stmt = $con->prepare("INSERT INTO updfiles (name, type, size, content) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssis", $name, $type, $size, $content);
$stmt->send_long_data(3, $content); // BLOB 需用 send_long_data
$stmt->execute();
echo "檔案已存入資料庫 (ID: {$stmt->insert_id})";
$stmt->close();
} else {
echo "上傳失敗: " . $err;
}
$con->close();
?>
fopen($tmp, 'rb') 二進位模式讀取UPLOAD_ERR_OK (0) 表上傳成功php.ini upload_max_filesize、post_max_size、MySQL max_allowed_packet$stmt = $con->prepare("SELECT type, content FROM updfiles WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->bind_result($type, $content);
$stmt->fetch();
header("Content-Type: $type");
echo $content;
| 優點 | 缺點 |
|---|---|
| 資料完整性(交易支援) | 資料庫體積暴增,備份慢 |
| 刪除同步,無孤兒檔 | 記憶體壓力大(BLOB 讀寫) |
| 權限控制集中在 DB | 無法直接 CDN 分發、瀏覽器快取 |
現代專案多採用「物件存儲 + 資料庫存路徑」架構。