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

PHP Session 完整指南:啟動、讀寫、銷毀與登入驗證實戰

     編輯:PHP 相關知識

Session 是 PHP 實現有狀態會話的核心機制,廣泛應用於用戶登入狀態維持、購物車、權限控制等場景。本文系統梳理 Session 核心操作、常見陷阱,並以「管理員登入驗證」為例展示完整實戰流程。

一、核心操作速查

操作代碼說明
啟動session_start();每個腳本最開頭呼叫,必須在任何輸出前
寫入$_SESSION['key'] = $value;支援陣列、物件(需實現 Serializable)
讀取$val = $_SESSION['key'] ?? null;使用 null 合併運算子避免 Notice
判斷存在isset($_SESSION['key'])不觸發 Notice
判斷為空empty($_SESSION['key'])包含未設定、null、空字串、0、false
刪除單鍵unset($_SESSION['key']);
銷毀整個 Sessionsession_destroy();僅刪除伺服器端資料,客戶端 Cookie 需另行清除
重新生成 IDsession_regenerate_id(true);防止 Session Fixation 攻擊,登入成功後必呼叫

二、配置優化(php.ini / 運行時)

// 安全相關
ini_set('session.cookie_httponly', 1);      // 禁止 JS 讀取 Cookie
ini_set('session.cookie_secure', 1);        // 僅 HTTPS 傳輸(生產環境必開)
ini_set('session.use_strict_mode', 1);      // 拒絕未初始化的 Session ID
ini_set('session.cookie_samesite', 'Lax');  // CSRF 防護

// 效能相關
ini_set('session.gc_maxlifetime', 7200);    // 垃圾回收壽命(秒)
ini_set('session.save_path', '/var/lib/php/sessions'); // 自定義存儲路徑(需權限)

三、實戰:管理員登入驗證完整流程

1. 登入表單

<!-- login.php -->
<form action="checklogin.php" method="post">
    <div>
        <label>用戶名:<input type="text" name="username" required></label>
    </div>
    <div>
        <label>密碼:<input type="password" name="password" required></label>
    </div>
    <button type="submit">登入</button>
</form>

2. 處理邏輯

<?php
// checklogin.php
require_once 'config/db.php';
session_start();

// 1. 獲取並驗證輸入
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';

if (!$username || !$password) {
    exit(json_encode(['code' => 400, 'msg' => '用戶名密碼不能為空']));
}

// 2. 查詢用戶(預處理防注入)
$stmt = $mysqli->prepare("SELECT id, username, password_hash FROM admin WHERE username = ?");
$stmt->bind_param('s', $username);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();

if (!$user) {
    exit(json_encode(['code' => 401, 'msg' => '用戶不存在']));
}

// 3. 驗證密碼(使用 password_hash/password_verify)
if (!password_verify($password, $user['password_hash'])) {
    exit(json_encode(['code' => 401, 'msg' => '密碼錯誤']));
}

// 4. 登入成功:重新生成 Session ID、寫入用戶標識
session_regenerate_id(true);
$_SESSION['admin_id'] = $user['id'];
$_SESSION['admin_name'] = $user['username'];
$_SESSION['login_time'] = time();

// 5. 返回成功
echo json_encode(['code' => 200, 'msg' => '登入成功', 'redirect' => 'index.php']);
// 或 header('Location: index.php');

3. 權限驗證中介層

<?php
// auth.php - 所有受保護頁面 require_once
session_start();

if (empty($_SESSION['admin_id'])) {
    // AJAX 請求返回 JSON,普通請求跳轉登入頁
    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
        header('Content-Type: application/json');
        exit(json_encode(['code' => 401, 'msg' => '未登入或登入過期']));
    }
    header('Location: login.php');
    exit;
}

// 可選:檢查權限等級
// if ($_SESSION['admin_level'] < REQUIRED_LEVEL) { exit('權限不足'); }

4. 登出處理

<?php
// logout.php
session_start();
$_SESSION = []; // 清空陣列
if (ini_get('session.use_cookies')) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params['path'], $params['domain'],
        $params['secure'], $params['httponly']
    );
}
session_destroy();
header('Location: login.php');

四、常見坑與避坑指南

  1. session_start() 之前有輸出:包括 BOM、空白字元、echo/print。解決:檔案儲存為 UTF-8 無 BOM,確保 session_start() 在最頂端。
  2. Session 資料丟失:檢查 session.save_path 目錄權限、磁碟空間、gc_maxlifetime 過短、多伺服器未共享 Session 存儲(需用 Redis/Memcached)。
  3. 並發阻塞:同一 Session 並發請求會串行(預設檔案鎖)。長耗時操作前呼叫 session_write_close() 釋放鎖。
  4. 跨子域共享:設定 session.cookie_domain = '.example.com'。

五、總結

Session 是 PHP 會話管理的基石。掌握 session_start() 時機、安全配置、密碼驗證最佳實踐、登入/登出完整流程,並理解常見坑點與分散式擴展方案,是合格 PHP 後端工程師的必備技能。本文提供的範本代碼可直接作為專案 Auth 模組的基礎骨架。

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