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

PHP Session 完整指南:建立、驗證、生命週期、安全與物件儲存

     編輯:PHP 綜合知識

Session vs Cookie:為何選 Session?

特性CookieSession
儲存位置客戶端瀏覽器伺服器端(檔案/資料庫/Redis)
安全性可被竄改、側錄、XSS 竊取用戶無法直接修改,相對安全
容量限制單餅乾 4KB、域名約 20-50 個伺服器磁碟/記憶體限制,幾乎無上限
傳輸開銷每請求自動攜帶(含靜態資源)僅傳 Session ID(Cookie/URL),體積極小
跨域共享需設定 Domain/Path需共用儲存介質(Redis/DB)

Session 核心運作機制

  1. session_start():啟動/恢復會話,讀取或建立 Session ID
  2. Session ID 傳遞方式:Cookie (預設)、URL 參數、隱藏表單
  3. 伺服器以 Session ID 為鍵,讀寫對應儲存資料($_SESSION 超全域陣列)
  4. 請求結束自動序列化寫回儲存介質

基本操作:啟動、寫入、讀取、銷毀

 123,
    'username' => 'john',
    'role'     => 'admin',
    'login_at' => time(),
];

// 3. 讀取
if (isset($_SESSION['user'])) {
    echo "歡迎,{$_SESSION['user']['username']}";
}

// 4. 刪除單一鍵
unset($_SESSION['user']['role']);

// 5. 完全銷毀(登出)
session_unset();     // 清空 $_SESSION
session_destroy();   // 刪除伺服器端儲存檔案
// 建議同步刪除客戶端 Cookie
if (ini_get('session.use_cookies')) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
?>

登入驗證完整流程範例

prepare("SELECT id, username, password_hash FROM users WHERE username=?");
    $stmt->execute([$username]);
    $user = $stmt->fetch();

    if ($user && password_verify($password, $user['password_hash'])) {
        // 2. 登入成功:重新生成 Session ID(防 Session Fixation)
        session_regenerate_id(true);

        // 3. 寫入必要資訊
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['last_activity'] = time();

        header('Location: dashboard.php');
        exit;
    }
    $error = '帳號或密碼錯誤';
}
// 顯示登入表單...
?>
 1800) {
    session_unset();
    session_destroy();
    header('Location: login.php?timeout=1');
    exit;
}
$_SESSION['last_activity'] = time();
// 正常顯示內容...
?>

Session 生命週期控制

方法一:session_set_cookie_params()(必須在 session_start() 前)

方法二:手動 setcookie() 控制 Session ID Cookie(相容 IE6、彈性最高)

客戶端禁用 Cookie 怎麼辦?

Session ID 會自動附加在 URL:?PHPSESSID=abc123。需啟用 session.use_trans_sid=1(php.ini)或手動傳遞。安全風險極高(URL 洩漏、快取、書籤),生產環境**強烈不建議**,應要求啟用 Cookie。

自訂儲存路徑與驅動(資料庫/Redis)

檔案儲存路徑

資料庫儲存(自定義 Session Handler)

pdo = $pdo; }
    public function open($savePath, $sessionName) { return true; }
    public function close() { return true; }
    public function read($id) {
        $stmt = $this->pdo->prepare("SELECT data FROM sessions WHERE id=? AND expiry>?");
        $stmt->execute([$id, time()]);
        return $stmt->fetchColumn() ?: '';
    }
    public function write($id, $data) {
        $expiry = time() + ini_get('session.gc_maxlifetime');
        $stmt = $this->pdo->prepare("INSERT INTO sessions (id,data,expiry) VALUES (?,?,?) ON DUPLICATE KEY UPDATE data=?,expiry=?");
        return $stmt->execute([$id, $data, $expiry, $data, $expiry]);
    }
    public function destroy($id) {
        $this->pdo->prepare("DELETE FROM sessions WHERE id=?")->execute([$id]);
        return true;
    }
    public function gc($maxlifetime) {
        $this->pdo->prepare("DELETE FROM sessions WHERE expiryexecute([time()]);
        return true;
    }
}

// 註冊
$handler = new DbSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();
?>

儲存物件與陣列:自動序列化

name"; }
}

session_start();
$user = new User();
$user->id = 1;
$user->name = 'Alice';
$_SESSION['user_obj'] = $user; // 自動 serialize()

// 下一請求自動 unserialize()
// 需確保類別定義已載入(autoload),否則會變成 __PHP_Incomplete_Class
// 解決:spl_autoload_register 或 session 開始前 require 類別檔
?>

安全最佳實務清單

  • HTTPS 全站:Cookie 設定 Secure、HttpOnly、SameSite=Strict
  • 登入後重新生成 ID:session_regenerate_id(true) 防 Session Fixation
  • 閒置逾時:伺服器端檢查 last_activity,配合 session.gc_maxlifetime
  • 權限最小化:Session 僅存 user_id、role,敏感資料查 DB
  • 分散式部署:必須使用 Redis/資料庫共用 Session,檔案儲存不支援多伺服器
  • 定期清理:session.gc_probability/gc_divisor 控制 GC 頻率

結語

Session 是 PHP 有狀態開發的基石。掌握啟動時機、生命週期控制、儲存驅動切換、安全防護四大核心,即可從簡單登入延伸至分散式系統的 Session 共享架構。現代專案建議直接使用框架封裝(Laravel session()、Symfony SessionInterface),專注業務邏輯。

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