首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP Session 儲存至資料庫完整實作指南

     編輯:PHP 相關知識

將 PHP Session 資料存入 MySQL 資料庫

預設 PHP Session 資料儲存在伺服器檔案系統中,但在分散式架構或負載平衡環境下,需將 Session 集中儲存於資料庫以實現共享。本文示範如何使用 session_set_save_handler() 自訂 Session 儲存機制,搭配 MySQL 資料表實作完整的讀寫、銷毀與垃圾回收流程。

資料表結構設計

建立 sessions 資料表,主鍵為 session_id,包含過期時間與序列化資料欄位:

CREATE TABLE `sessions` (
  `session_id` varchar(255) NOT NULL,
  `session_expires` int(11) DEFAULT NULL,
  `session_data` text,
  PRIMARY KEY (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

自訂 Session 處理類別

實作 SessionHandlerInterface 介面所需的六個方法:open、close、read、write、destroy、gc。以下為核心程式碼架構(已移除舊版 mysql_* 函數,建議實際專案改用 PDO 或 MySQLi):

<?php
class SessionHandler {
    private $lifeTime;
    private $dbHandle;

    public function open($savePath, $sessName) {
        $this->lifeTime = ini_get('session.gc_maxlifetime');
        // 建議使用 PDO 連線
        $this->dbHandle = new PDO('mysql:host=localhost;dbname=mysession', 'root', 'root');
        return true;
    }

    public function close() {
        $this->gc(ini_get('session.gc_maxlifetime'));
        $this->dbHandle = null;
        return true;
    }

    public function read($sessID) {
        $stmt = $this->dbHandle->prepare('SELECT session_data FROM sessions WHERE session_id = ? AND session_expires > ?');
        $stmt->execute([$sessID, time()]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? $row['session_data'] : '';
    }

    public function write($sessID, $sessData) {
        $newExp = time() + $this->lifeTime;
        $stmt = $this->dbHandle->prepare('REPLACE INTO sessions (session_id, session_expires, session_data) VALUES (?, ?, ?)');
        return $stmt->execute([$sessID, $newExp, $sessData]);
    }

    public function destroy($sessID) {
        $stmt = $this->dbHandle->prepare('DELETE FROM sessions WHERE session_id = ?');
        return $stmt->execute([$sessID]);
    }

    public function gc($maxLifeTime) {
        $stmt = $this->dbHandle->prepare('DELETE FROM sessions WHERE session_expires < ?');
        $stmt->execute([time()]);
        return $stmt->rowCount();
    }
}

// 註冊處理器並啟動 Session
$handler = new SessionHandler();
session_set_save_handler($handler, true);
session_start();

// 測試寫入資料
$_SESSION['user'] = ['name' => 'gxx', 'pass' => '123'];
?>

運作流程解析

  1. open:建立資料庫連線,取得 Session 生命週期設定。
  2. read:依 session_id 查詢有效資料,若過期則回傳空字串觸發新 Session。
  3. write:使用 REPLACE INTO 同時處理新增與更新,避免競態條件。
  4. destroy:用戶登出時刪除對應記錄。
  5. gc:定期清理過期 Session,防止資料表膨脹。

安全性與效能建議

  • 務必使用預處理語句防止 SQL 注入。
  • 資料庫連線建議採用連線池或持久連線減少開銷。
  • Session 資料經 PHP 內建序列化,資料庫欄位型別用 TEXT 或 LONGTEXT。
  • 生產環境應啟用 session.use_strict_mode 並設定適當的 session.gc_probability。

透過資料庫儲存 Session,可輕鬆支援多伺服器叢集架構,是打造高可用性 PHP 應用的關鍵技術之一。

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