首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP 將圖片等二進位檔案儲存至 MySQL 資料庫完整教學

     編輯:MySQL 資料庫相關知識

將圖片、文件等二進位資料直接存入 MySQL 資料庫,雖非主流架構(通常建議存檔案路徑),但在特定需求下(如資料完整性、備份簡化、跨伺服器同步)仍具優勢。本文示範建立資料表、上傳儲存、讀取輸出的完整流程。

1. 建立資料庫與資料表

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 二進位資料,適合圖片、PDF 等檔案。
  • 同時記錄檔名、大小、MIME 型別,方便後續輸出時設定正確 Header。

2. 上傳儲存程式 (store.php)

<?php
// store.php
if (isset($_POST['submit'])) {
    // 連線資料庫(請修改為實際帳密)
    $conn = mysqli_connect("localhost", "root", "password", "binary_data");
    if (!$conn) die("連線失敗: " . mysqli_connect_error());

    // 取得上傳檔案資訊
    $tmpName  = $_FILES['form_data']['tmp_name'];
    $name     = $_FILES['form_data']['name'];
    $size     = $_FILES['form_data']['size'];
    $type     = $_FILES['form_data']['type'];
    $desc     = mysqli_real_escape_string($conn, $_POST['form_description']);

    // 讀取二進位內容並逃脫
    $fp      = fopen($tmpName, 'r');
    $content = fread($fp, $size);
    fclose($fp);
    $data    = mysqli_real_escape_string($conn, $content);

    // 寫入資料庫
    $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";
    } else {
        echo "錯誤: " . mysqli_error($conn);
    }
    mysqli_close($conn);
} else {
?>

檔案描述:

選擇檔案:

<?php } ?>

關鍵點:

  • 表單需加 enctype="multipart/form-data"。
  • 使用 $_FILES 取得暫存檔路徑、原始檔名、大小、型別。
  • mysqli_real_escape_string() 防止二進位資料中的特殊字元破壞 SQL。
  • 回傳的 mysqli_insert_id() 即為該筆記錄的主鍵 ID,前端可記錄以便後續讀取。

3. 讀取輸出程式 (getdata.php)

<?php
// getdata.php?id=2
if (isset($_GET['id'])) {
    $id = (int)$_GET['id']; // 強制轉整數防注入
    $conn = mysqli_connect("localhost", "root", "password", "binary_data");
    if (!$conn) die("連線失敗");

    $sql = "SELECT bin_data, filetype FROM binary_data WHERE id = $id";
    $result = mysqli_query($conn, $sql);
    if ($row = mysqli_fetch_assoc($result)) {
        header("Content-Type: " . $row['filetype']);
        echo $row['bin_data'];
    } else {
        header("HTTP/1.0 404 Not Found");
        echo "找不到指定檔案";
    }
    mysqli_close($conn);
} else {
    echo "請提供 id 參數";
}
?>

使用方式:

  • 直接在瀏覽器開啟 getdata.php?id=3 即可顯示圖片。
  • HTML 中可直接引用:<img src="getdata.php?id=3">。

4. 儲存大檔案(>1MB)的設定調整

預設 PHP、MySQL 限制上傳與封包大小,需調整下列參數(以 24MB 為例):

層面設定項目建議值
HTML 表單<input type="hidden" name="MAX_FILE_SIZE" value="24000000">24000000
PHP (php.ini)upload_max_filesize24M
PHP (php.ini)post_max_size24M
PHP (php.ini)max_execution_time0 (無限制) 或較大秒數
MySQL 啟動參數max_allowed_packet24M
MySQL 設定檔 (my.cnf/my.ini)[mysqld] max_allowed_packet=24M24M

修改 my.cnf 後需重啟 MySQL 服務生效。若仍失敗,請檢查錯誤日誌確認是否為記憶體或逾時問題。

5. 安全與效能提醒

  • SQL 注入防護:務必使用 Prepared Statements(mysqli_prepare / PDO)取代字串拼接。
  • 檔案型別驗證:不要完全信任 $_FILES['type'],建議搭配 finfo_file() 檢測真實 MIME。
  • 資料庫膨脹:大量二進位資料會讓備份、複製、遷移變慢,評估是否改用物件儲存(S3、MinIO)或檔案系統 + 路徑資料庫的混合架構。
  • 輸出快取:在 getdata.php 加入 ETag、Last-Modified、Cache-Control 標頭,減少重複傳輸。

掌握上述流程,即可在 PHP 專案中靈活處理二進位檔案的資料庫儲存與讀取。實務上請根據專案規模與維運考量,權衡「存 DB」與「存檔案系統」的優劣。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved