相比 Cookie 存儲在客戶端、易被竄改、有大小限制,Session 數據存儲在服務端,安全性更高,且無長度限制。本文系統講解 Session 登錄驗證全流程,含生命周期控制、跨頁面驗證、對象存儲、自定義存儲路徑等進階用法。
$_SESSION['admin'] = true,後續頁面只判斷該值,無需每次查庫驗證密碼。login.php<?php
// 接收表單提交
$posts = $_POST;
foreach ($posts as $key => $value) {
$posts[$key] = trim($value);
}
$username = $posts['username'];
$password = md5($posts['password']); // 實際建議用 password_hash()
// 查詢數據庫(示例用簡易寫法,實際請用預處理語句防注入)
$query = "SELECT `username` FROM `user` WHERE `username` = '$username' AND `password` = '$password'";
$userInfo = $DB->getRow($query);
if (!empty($userInfo)) {
session_start();
$_SESSION['admin'] = true; // 標記登錄狀態
$_SESSION['username'] = $username; // 可選:存用戶名
header('Location: dashboard.php');
exit;
} else {
die('用戶名或密碼錯誤');
}
?>
<?php
$admin = false; // 防全局變量污染
session_start();
if (isset($_SESSION['admin']) && $_SESSION['admin'] === true) {
echo "您已成功登錄,歡迎 " . ($_SESSION['username'] ?? '用戶');
} else {
$_SESSION['admin'] = false;
die('您無權訪問,請 登錄');
}
?>
logout.php<?php
session_start();
// 方式一:銷毀單個變量
unset($_SESSION['admin']);
// 方式二:銷毀整個 Session(推薦徹底登出)
session_destroy();
header('Location: login.php');
?>
默認關閉瀏覽器即失效。若需「記住我」功能(如保持 1 天):
<?php
// 方法一:手動 setcookie 綁定 Session ID 生命周期
session_start();
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, '/');
// 方法二:session_set_cookie_params() 必須在 session_start() 之前調用
$lifeTime = 24 * 3600;
session_set_cookie_params($lifeTime);
session_start();
$_SESSION['admin'] = true;
?>
注意:IE6 下 session_set_cookie_params() 有 Bug,建議統一用方法一。
<?php
$lifeTime = 24 * 3600;
$sessionName = session_name(); // 默認 PHPSESSID
$sessionID = $_GET[$sessionName] ?? '';
if ($sessionID) session_id($sessionID); // 手動設置 ID
session_set_cookie_params($lifeTime);
session_start();
$_SESSION['admin'] = true;
?>
此時 URL 形如 page.php?PHPSESSID=abc123...,需注意不要在郵件/外鏈中泄露帶 SID 的 URL。
<?php
$savePath = '/home/user/session_data/'; // 必須不可 Web 訪問、可讀寫
session_save_path($savePath); // 必須在 session_start() 前調用
session_set_cookie_params(24 * 3600);
session_start();
$_SESSION['admin'] = true;
?>
<?php
// person.php
class Person {
public $age;
public function setAge($age) { $this->age = $age; }
public function output() { echo $this->age; }
}
// setage.php
session_start();
require_once 'person.php';
$p = new Person();
$p->setAge(21);
$_SESSION['person'] = $p; // PHP 自動 serialize
echo '<a href="output.php">查看年齡</a>';
// output.php
ini_set('unserialize_callback_func', 'mycallback');
function mycallback($classname) { include_once $classname . '.php'; }
session_start();
$person = $_SESSION['person']; // PHP 自動 unserialize
$person->output(); // 輸出 21
?>
關鍵:反序列化時類定義必須已加載,unserialize_callback_func 回調可自動載入類文件。
若需將 Session 存入 Redis、MySQL 或實現分布式共享,請使用 session_set_save_handler() 註冊自定義讀寫回調(見下文專文)。