默認 PHP Session 以文件形式存儲於服務器磁盤,集群環境下需共享存儲(NFS/Redis/DB)。數據庫方案優勢:無額外組件依賴、支持事務、便於統計在線用戶、可攜帶自定義字段(User-Agent、IP)增強安全性。
static,無需實例化;User-Agent MD5 及客戶端 IP,防止 Session 劫持;gc() 清理過期數據;fetchRow(
"SELECT session_id, value, agent, ip FROM " . self::$table .
" WHERE session_id = ? AND expiry > ?",
[$sid, $expire]
);
if (!$rs || $rs['agent'] !== $agent || $rs['ip'] !== $ip) return false;
self::$session_id = $rs['session_id'];
return unserialize($rs['value']);
}
// 寫入/更新 Session
private static function write(array $data) {
$sid = self::$session_id ?: self::get_session_id();
$expire = TIME + self::$gc_max_time;
$agent = isset($_SERVER['HTTP_USER_AGENT']) ? md5($_SERVER['HTTP_USER_AGENT']) : '';
$ip = Fun::getIp();
$val = serialize($data);
if ($sid && $sid === self::$session_id) {
self::$dbo->query(
"UPDATE " . self::$table . " SET value=?, expiry=?, agent=?, ip=? WHERE session_id=?",
[$val, $expire, $agent, $ip, $sid]
);
} else {
$sid = self::create_session_id();
self::$dbo->query(
"INSERT INTO " . self::$table . " (session_id, value, expiry, agent, ip) VALUES (?,?,?,?,?)",
[$sid, $val, $expire, $agent, $ip]
);
self::$session_id = $sid;
}
return true;
}
// 生成 Session ID 並寫入 Cookie
private static function create_session_id() {
$sid = self::get_session_id();
if (!$sid) {
$sid = md5(self::$pre_key . Fun::getIp() . TIME . microtime(true) . mt_rand());
$sid = substr($sid, 0, 32);
setcookie('WBSID', $sid, TIME + self::$gc_max_time, self::$path, self::$domain, self::$secure, self::$httponly);
}
return $sid;
}
// 公開 API
public static function set($key, $val = null) { /* ... */ }
public static function get($key = null) { /* ... */ }
public static function del($key) { /* ... */ }
public static function destroy() { /* ... */ }
// 垃圾回收、關閉等內部方法省略...
}
CREATE TABLE `sessions` ( `session_id` VARCHAR(32) NOT NULL PRIMARY KEY, `value` TEXT NOT NULL, `expiry` INT(11) UNSIGNED NOT NULL, `agent` VARCHAR(32) NOT NULL DEFAULT '', `ip` VARCHAR(45) NOT NULL DEFAULT '', INDEX `idx_expiry` (`expiry`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
require 'Session.php';
// 寫入
Session::set('user_id', 12345);
Session::set(['nickname' => '張三', 'role' => 'admin']);
// 讀取
$userId = Session::get('user_id');
$all = Session::get(); // 返回全部數組
// 刪除單鍵
Session::del('user_id');
// 銷毀整個 Session
Session::destroy();
session_id 哈希分表;