使用 LONGBLOB 儲存二進位檔案 (圖片、文件) 的最小化 PHP 範例,含建表、寫入、讀取、輸出與大檔案限制說明。
CREATE TABLE testtable (
id INT(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
filename CHAR(255),
data LONGBLOB
);
<?php
$conn = mysql_connect("localhost", "root", "password");
mysql_select_db("database", $conn);
$filename = "/path/to/file.bin"; // 實際檔案路徑
$fp = fopen($filename, 'rb');
$data = fread($fp, filesize($filename));
fclose($fp);
$data = addslashes($data); // 必須轉義
$sql = "INSERT INTO testtable (filename, data) VALUES ('$filename', '$data')";
mysql_query($sql, $conn);
mysql_close($conn);
?>
<?php
$id = 1; // 目標 ID
$conn = mysql_connect("localhost", "root", "password");
mysql_select_db("database", $conn);
$sql = "SELECT data FROM testtable WHERE id = $id";
$result = mysql_query($sql, $conn);
$data = mysql_result($result, 0, "data");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"file.bin\"");
echo $data;
mysql_close($conn);
?>
| 限制 | 舊版影響 | 解決方案 |
|---|---|---|
PHP memory_limit | 預設 128MB,大檔案 OOM | 分塊讀寫 / stream_copy_to_stream |
MySQL max_allowed_packet | 預設 4/16/64MB,超過截斷 | 設定 > 最大檔案 (如 256M) |
mysql_* API | PHP 7.0 移除 | 改用 mysqli / PDO |
| SQL 注入 | addslashes 不完整 | Prepared Statement + send_long_data |
$stmt = $mysqli->prepare("INSERT INTO testtable (filename, data) VALUES (?, ?)");
$stmt->bind_param("sb", $filename, $data); // 'b' = blob
$fp = fopen($filename, 'rb');
while (!feof($fp)) {
$chunk = fread($fp, 8192);
$stmt->send_long_data(1, $chunk); // 參數索引 1 = data
}
$stmt->execute();
資料庫存檔適合 小檔案 (≤ 10MB)、低併發、需 ACID。大檔案/高併發請用 物件儲存 (S3/MinIO) + 資料庫存 URL。現代代碼務必使用 mysqli/PDO + Prepared Statement + 分塊傳輸。