本文示範將上傳文件二進位內容直接寫入 MySQL `BLOB` 欄位的完整流程。**注意:原文使用已棄用移除的 `mysql_*` 函數,下方代碼已升級為 PDO 預處理語句,防止 SQL 注入並相容 PHP 7/8。**
CREATE TABLE `receive` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `file_name` VARCHAR(255) NOT NULL, `file_type` VARCHAR(100) NOT NULL, `file_size` INT UNSIGNED NOT NULL, `file_data` LONGBLOB NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
<!DOCTYPE html> <html><head><meta charset="utf-8"><title>文件上傳</title></head><body> <form action="submit.php" method="post" enctype="multipart/form-data"> <input type="hidden" name="MAX_FILE_SIZE" value="1000000"> <p>選擇檔案:<input type="file" name="myfile"></p> <p><input type="submit" name="submit" value="上傳"></p> </form> </body></html>
<?php
require_once 'db.php';
if (!isset($_FILES['myfile']) || $_FILES['myfile']['error'] !== UPLOAD_ERR_OK) {
die('未收到有效上傳檔案或上傳出錯:' . ($_FILES['myfile']['error'] ?? '未知'));
}
$file = $_FILES['myfile'];
$tmp = $file['tmp_name'];
// 讀取二進位內容
$data = file_get_contents($tmp);
if ($data === false) die('讀取暫存檔失敗');
// 刪除暫存檔 (PHP 會在腳本結束自動清理,顯式調用更保險)
@unlink($tmp);
// 準備元資料
$name = $file['name'];
$type = $file['type'] ?: 'application/octet-stream';
$size = $file['size'];
// 寫入資料庫 (PDO 預處理,防注入)
try {
$pdo = getPDO(); // 見 db.php
$stmt = $pdo->prepare(
'INSERT INTO `receive` (file_name, file_type, file_size, file_data) VALUES (?, ?, ?, ?)'
);
$stmt->bindParam(1, $name, PDO::PARAM_STR);
$stmt->bindParam(2, $type, PDO::PARAM_STR);
$stmt->bindParam(3, $size, PDO::PARAM_INT);
$stmt->bindParam(4, $data, PDO::PARAM_LOB); // 關鍵:LOB 參數綁定
$stmt->execute();
$id = $pdo->lastInsertId();
echo "上傳成功!<a href='show_info.php?id=$id'>查看檔案資訊</a>";
} catch (PDOException $e) {
error_log('Upload DB Error: ' . $e->getMessage());
die('資料庫寫入失敗,請稍後重試');
}
<?php
require_once 'db.php';
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
if (!$id) die('缺少 ID');
$pdo = getPDO();
$stmt = $pdo->prepare('SELECT file_name, file_size FROM receive WHERE id = ?');
$stmt->execute([$id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) die('記錄不存在');
echo "<hr>上傳檔案資訊:<br>";
echo "檔案名:{$row['file_name']}<br>";
echo "大小:{$row['file_size']} bytes<br>";
echo "<a href='show_file.php?id=$id'>下載檔案</a>";
<?php
require_once 'db.php';
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
if (!$id) die('缺少 ID');
$pdo = getPDO();
$stmt = $pdo->prepare('SELECT file_data, file_type, file_name FROM receive WHERE id = ?');
$stmt->execute([$id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) die('記錄不存在');
// 輸出檔案頭
header('Content-Type: ' . $row['file_type']);
header('Content-Disposition: attachment; filename="' . rawurlencode($row['file_name']) . '"');
header('Content-Length: ' . strlen($row['file_data']));
echo $row['file_data'];
<?php
function getPDO()
{
static $pdo = null;
if ($pdo === null) {
$dsn = 'mysql:host=127.0.0.1;dbname=test;charset=utf8mb4';
$pdo = new PDO($dsn, 'username', 'password', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 使用真實預處理
]);
}
return $pdo;
}