Cookie 是 HTTP 協議中實現會話狀態的關鍵機制。PHP 通過 setcookie() 向瀏覽器發送 Cookie,後續請求會自動攜帶。本文從基礎語法到完整登錄案例,系統講解 Cookie 的全生命周期管理。
setcookie(string $name, string $value, int $expire = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool
| 參數 | 說明 |
|---|---|
name | Cookie 名稱(必填) |
value | Cookie 值(必填),自動 URL 編碼 |
expire | 過期時間戳(秒),0 表示會話結束失效 |
path | 生效路徑,默認當前目錄 |
domain | 生效域名,支持子域共享 |
secure | 僅 HTTPS 傳輸 |
httponly | 禁止 JavaScript 訪問,防 XSS |
<?php
// 簡單設置(會話級)
setcookie('mycookie', 'value');
// 1 小時後過期
setcookie('withExpire', 'Expire_in_1_hour', time() + 3600);
// 完整參數
setcookie('FullCookie', 'Full_cookie_value', time() + 3600, '/forum', 'www.example.com', true, true);
?>
<?php
// 推薦使用 $_COOKIE 超全局變量
echo $_COOKIE['mycookie'] ?? '未設置';
// 兼容舊版本
echo $HTTP_COOKIE_VARS['mycookie'] ?? '未設置';
?>
本質是將過期時間設為過去:
<?php
// 推薦寫法:設置值為空並過期
setcookie('mycookie', '', time() - 3600);
// 等效寫法
setcookie('mycookie');
setcookie('mycookie', '');
setcookie('mycookie', false);
?>
為了在客戶端也能知道過期時間,可雙 Cookie 存儲:
<?php
$expire = time() + 86400; // 24 小時
setcookie('var_name', 'var_value', $expire);
setcookie('var_name_expire', $expire, $expire); // 同步過期時間
?>
connectvars.php<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASSWORD', '19900101');
define('DB_NAME', 'test');
?>
logIn.php<?php
require_once 'connectvars.php';
$error_msg = '';
// 已登錄則跳轉
if (isset($_COOKIE['user_id'])) {
header('Location: loged.php');
exit;
}
if (isset($_POST['submit'])) {
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$username = mysqli_real_escape_string($dbc, trim($_POST['username']));
$password = mysqli_real_escape_string($dbc, trim($_POST['password']));
if (!empty($username) && !empty($password)) {
// 使用 SHA 加密驗證(生產環境建議用 password_hash)
$query = "SELECT user_id, username FROM mismatch_user WHERE username = '$username' AND password = SHA('$password')";
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) === 1) {
$row = mysqli_fetch_array($data);
setcookie('user_id', $row['user_id'], time() + 3600);
setcookie('username', $row['username'], time() + 3600);
header('Location: loged.php');
exit;
} else {
$error_msg = '用戶名或密碼錯誤';
}
} else {
$error_msg = '請填寫完整信息';
}
}
?>
<html>
<head><title>登錄</title></head>
<body>
<h3>用戶登錄</h3>
<?php if (!empty($error_msg)): ?><p class="error"><?= $error_msg ?></p><?php endif; ?>
<form method="post" action="= $_SERVER['PHP_SELF'] ?>">
<label>用戶名: <input type="text" name="username" value="= htmlspecialchars($username ?? '') ?>"></label><br>
<label>密碼: <input type="password" name="password"></label><br>
<input type="submit" name="submit" value="登錄">
</form>
</body>
</html>
loged.php<?php
if (isset($_COOKIE['username'])) {
echo '歡迎,' . htmlspecialchars($_COOKIE['username']) . '<br>';
echo '<a href="logOut.php">退出登錄</a>';
} else {
header('Location: logIn.php');
}
?>
logOut.php<?php
if (isset($_COOKIE['user_id'])) {
setcookie('user_id', '', time() - 3600);
setcookie('username', '', time() - 3600);
}
header('Location: logIn.php');
?>
setcookie 從後往前生效,需先寫入再刪除。path=/。httponly 與 secure,防止 XSS 與中間人攻擊。setrawcookie()。掌握以上內容,即可靈活運用 Cookie 實現會話管理、記住登錄等常見功能。