函數定義
<?php
/**
* 檢查使用者閒置時間,超過門檻自動銷毀 Session 並終止腳本
*
* @param int $lastActivity 上次活動時間戳 (來自 $_SESSION['last_activity'])
* @param int $idleLimit 允許閒置秒數 (預設 3600 = 1小時)
*/
function checkIdleTimeout($lastActivity, $idleLimit = 3600)
{
$now = time();
if ($now - $lastActivity > $idleLimit) {
// 閒置超時
session_unset();
session_destroy();
// 可選:記錄登出日誌、重導登入頁
exit('登入逾時,請重新登入');
}
// 更新最後活動時間
$_SESSION['last_activity'] = $now;
}
// 使用:每支受保護頁面頂部引入
session_start();
checkIdleTimeout($_SESSION['last_activity'] ?? 0, 1800); // 30 分鐘
?>
整合進入口檔 (bootstrap.php)
<?php
// bootstrap.php - 專案共用引入檔
session_start();
// 安全設定
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', isset($_SERVER['HTTPS']));
ini_set('session.use_strict_mode', 1);
// 閒置逾時檢查 (30 分鐘)
$idleLimit = 1800;
if (isset($_SESSION['last_activity']) && time() - $_SESSION['last_activity'] > $idleLimit) {
session_unset();
session_destroy();
header('Location: login.php?timeout=1');
exit;
}
$_SESSION['last_activity'] = time();
// 資料庫連線、常數定義、自動載入...
require __DIR__ . '/config/database.php';
require __DIR__ . '/vendor/autoload.php';
?>
進階:異步活動心跳 (AJAX)
<?php
// heartbeat.php - 前端每分鐘呼叫一次
session_start();
$_SESSION['last_activity'] = time();
echo json_encode(['ok' => true, 'server_time' => time()]);
?>
// 前端 JS (jQuery)
setInterval(() => {
$.get('heartbeat.php');
}, 60000); // 1 分鐘
注意事項
session.gc_maxlifetime (php.ini) 必須 ≥ 閒置門檻,否則 GC 會先刪除 Session 檔案
- 分散式部署需共用 Session 儲存 (Redis/Memcached/Database)
- 關鍵操作 (付費、刪除) 應重新驗證密碼或 2FA,不僅依賴閒置檢查