HTTP 協議無狀態,Session 通過 PHPSESSID Cookie 在客戶端標識用戶身份,服務端以文件(預設)、Redis、Memcached 等方式存儲會話數據。Session 過期由兩個獨立機制控制:
session.cookie_lifetime 控制 Cookie 存活時間session.gc_maxlifetime 控制數據文件最大生存時間,配合 GC 機率 (gc_probability/gc_divisor) 回收用戶花費 30 分鐘填寫大表單,提交時發現 Session 已被 GC 回收,被迫重新登錄並丟失數據——這是典型的用戶體驗災難。
<?php
// php.ini 或運行時設置
ini_set('session.gc_maxlifetime', 7200); // 2 小時
ini_set('session.cookie_lifetime', 7200); // Cookie 同步延長
?>
缺點:所有用戶 Session 文件堆積,佔用磁盤空間,GC 掃描開銷增加。
僅在需要長時間保持的頁面(如大表單)植入 JS 定時請求,刷新 Session 訪問時間:
<!-- 頁面嵌入 -->
<script>
function keepSessionAlive() {
var img = document.getElementById('session-keeper');
if (img) {
img.src = '/session/keepalive.php?' + Math.random(); // 避免緩存
}
}
// 每 4 分鐘發送一次心跳
setInterval(keepSessionAlive, 4 * 60 * 1000);
</script>
<img id="session-keeper" src="/session/keepalive.php" width="1" height="1" style="display:none" />
後端 keepalive.php:
<?php
session_start();
// 僅需啟動 session,自動更新文件 atime
// 可選:返回簡單響應
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'); // 1x1 透明 GIF
?>
結合 Session 保活與數據本地化,雙重保障:
<script>
function backupFormData() {
var formData = $('#long-form').serialize();
$.post('/form/autosave', formData, function(res) {
console.log('自動保存:', res.timestamp);
});
}
setInterval(backupFormData, 30000); // 30 秒備份一次
</script>
用戶即使 Session 失效、瀏覽器崩潑、網絡中斷,返回頁面時也能從服務端或 localStorage 恢復填寫進度。
PHP 官方文檔明確指出:Session 無法保證信息僅對創建者可見。長時間延長 Session 增加被劫持風險(Session Fixation、Sidejacking)。
session.cookie_secure = 1session.use_strict_mode = 1 拒絕未初始化 IDsession_regenerate_id(true)<!-- 方案:Meta Refresh 降級 -->
<noscript>
<meta http-equiv="refresh" content="240;url=/session/keepalive.php" />
<p>您的瀏覽器禁用了 JavaScript,頁面將每 4 分鐘自動刷新以保持登錄狀態。</p>
</noscript>
| 場景 | 推薦方案 | 關鍵點 |
|---|---|---|
| 內部管理系統、長表單 | 方案二 + 方案三 | 精準保活 + 數據備份雙保險 |
| 高安全要求業務 | 方案三 + 短 Session | 數據不丟失,Session 短更安全 |
| 簡單頁面、低頻操作 | 方案一(謹慎) | 設置合理 maxlifetime,配合定期清理 |
「用戶數據不丟失」永遠優於「Session 不過期」。採用 AJAX 自動保存 + 短 Session + 關鍵操作二次驗證 的組合策略,才是現代 Web 應用的最佳實踐。