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

將 PHP Session 儲存至 MySQL 資料庫:提升安全性與叢集支援的完整實作

     編輯:MySQL 資料庫相關知識

為什麼要將 Session 存入資料庫?

  • 安全性:預設 /tmp 目錄權限過於開放,易遭本地使用者竊取 Session ID 冒用身分。
  • 叢集支援:多台 Web Server 共享同一 Session 存儲,無需 NFS 掛載或 Sticky Session。
  • 可控性:可自訂 GC 機制、加密儲存、稽核追蹤。

資料表結構

CREATE TABLE sesslib (
    id      INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    sid     VARCHAR(32) NOT NULL UNIQUE,
    data    TEXT,
    time    DATETIME,
    INDEX idx_time (time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

自訂 Session Handler (XX.php)

<?php
$sess_dbh = null;
$sess_maxlifetime = ini_get("session.gc_maxlifetime");

function sess_open($save_path, $session_name) {
    global $sess_dbh;
    $sess_dbh = mysql_pconnect('localhost', 'test', 'test') or die("DB連線失敗");
    mysql_select_db('test', $sess_dbh) or die("選擇資料庫失敗");
    return true;
}

function sess_close() { return true; }

function sess_read($sid) {
    global $sess_dbh;
    $sid = mysql_real_escape_string($sid);
    $res = mysql_query("SELECT data FROM sesslib WHERE sid='$sid'", $sess_dbh);
    return ($row = mysql_fetch_row($res)) ? $row[0] : '';
}

function sess_write($sid, $sess_data) {
    global $sess_dbh;
    $sid = mysql_real_escape_string($sid);
    $data = mysql_real_escape_string($sess_data);
    $sql = "INSERT INTO sesslib (sid, data, time) VALUES ('$sid', '$data', NOW())
            ON DUPLICATE KEY UPDATE data='$data', time=NOW()";
    return mysql_query($sql, $sess_dbh);
}

function sess_destroy($sid) {
    global $sess_dbh;
    $sid = mysql_real_escape_string($sid);
    return mysql_query("DELETE FROM sesslib WHERE sid='$sid'", $sess_dbh);
}

function sess_gc($maxlifetime) {
    global $sess_dbh;
    $limit = date('Y-m-d H:i:s', time() - $maxlifetime);
    return mysql_query("DELETE FROM sesslib WHERE time < '$limit'", $sess_dbh);
}

// 註冊處理器
session_set_save_handler(
    'sess_open', 'sess_close',
    'sess_read', 'sess_write',
    'sess_destroy', 'sess_gc'
);
session_start();
// 之後正常使用 $_SESSION
?>

關鍵優化點

  • ON DUPLICATE KEY UPDATE:單一 SQL 處理新增/更新,避免競態條件。
  • mysql_real_escape_string:防止 SQL 注入(舊版用 addslashes)。
  • 索引優化:sid 唯一索引加速查找;time 索引加速 GC 掃描。
  • 資料加密:敏感資料可在 write/read 時搭配 openssl_encrypt/decrypt。

生產環境建議

  1. 使用 PDO/Mysqli 預處理語句替代 mysql_*。
  2. 啟用 session.use_strict_mode=1 防止 Session 固定攻擊。
  3. 搭配 Redis/Memcached 作為 L2 快取,降低 DB 壓力。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved