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

PHP Cookie 完整教學:設定、讀取、資料庫整合與用戶識別實戰

     編輯:PHP 綜合知識

Cookie 基本原理

Cookie 是伺服器透過 HTTP 標頭 Set-Cookie 要求瀏覽器儲存的小型資料片段。瀏覽器後續請求同域名會自動帶入 Cookie 標頭。PHP 自動解析並填入 $_COOKIE 超全域陣列。

setcookie() 完整語法

setcookie(
    string $name,           // Cookie 名稱
    string $value = "",     // 值 (自動 urlencode)
    int $expires = 0,       // 過期 Unix 時間戳 (0 = 瀏覽器關閉失效)
    string $path = "",      // 生效路徑 (預設為當前腳本目錄)
    string $domain = "",    // 生效域名 (預設為當前域名,需包含兩個點如 .example.com)
    bool $secure = false,   // 僅 HTTPS 傳輸
    bool $httponly = false  // 僅 HTTP 存取,JS document.cookie 不可讀 (防 XSS)
);

關鍵限制:setcookie() 必須在**任何輸出之前**呼叫 (含空白、BOM),否則觸發 Headers already sent 錯誤。

實戰範例:用戶識別 + 訪問計數 + 資料庫同步

資料表設計

CREATE TABLE users (
    FirstName VARCHAR(20),
    LastName  VARCHAR(40),
    email     VARCHAR(40) PRIMARY KEY,
    count     INT DEFAULT 1
);

index.php - 首頁邏輯

<?php
// 1. 檢查 Cookie 是否存在
if (isset($_COOKIE['Example'])) {
    // 2. 解析 Cookie 值 (格式: FirstName&LastName&email&count)
    [$FirstName, $LastName, $email, $count] = explode('&', $_COOKIE['Example']);
    $count++;
    
    // 3. 更新 Cookie (延長 1 小時)
    $newVal = implode('&', [$FirstName, $LastName, $email, $count]);
    setcookie('Example', $newVal, time() + 3600);
    
    // 4. 同步更新資料庫
    $pdo = new PDO('mysql:host=localhost;dbname=users', 'user', 'pass');
    $stmt = $pdo->prepare("UPDATE users SET count = ? WHERE FirstName = ? AND LastName = ? AND email = ?");
    $stmt->execute([$count, $FirstName, $LastName, $email]);
    
    // 5. 顯示歡迎頁面
    echo "<h1>Hello $FirstName $LastName</h1>";
    echo "<p>這是您的第 $count 次訪問</p>";
    echo "<p>Email: $email</p>";
} else {
    // 無 Cookie -> 引導註冊
    echo '<a href="reg.php">請先註冊</a>';
}
?>

reg.php - 註冊表單

<form method="post" action="reg1.php">
  名字: <input name="FirstName" required><br>
  姓氏: <input name="LastName" required><br>
  Email: <input type="email" name="email" required><br>
  <button type="submit">註冊</button>
</form>

reg1.php - 註冊處理

<?php
$FirstName = trim($_POST['FirstName'] ?? '');
$LastName  = trim($_POST['LastName'] ?? '');
$email     = trim($_POST['email'] ?? '');

if (!$FirstName || !$LastName || !$email) {
    die('資料不完整,請返回');
}

$pdo = new PDO('mysql:host=localhost;dbname=users', 'user', 'pass');

// 檢查是否已註冊
$stmt = $pdo->prepare("SELECT count FROM users WHERE FirstName = ? AND LastName = ? AND email = ?");
$stmt->execute([$FirstName, $LastName, $email]);
$row = $stmt->fetch();

if ($row) {
    // 舊用戶:計數+1,更新 Cookie
    $count = $row['count'] + 1;
    $pdo->prepare("UPDATE users SET count = ? WHERE email = ?")->execute([$count, $email]);
} else {
    // 新用戶:寫入資料庫,計數=1
    $count = 1;
    $pdo->prepare("INSERT INTO users (FirstName, LastName, email, count) VALUES (?, ?, ?, ?)")
        ->execute([$FirstName, $LastName, $email, $count]);
}

// 設定 Cookie (有效期 1 小時)
$cookieVal = implode('&', [$FirstName, $LastName, $email, $count]);
setcookie('Example', $cookieVal, time() + 3600);

echo "註冊成功!<a href='index.php'>進入首頁</a>";
?>

安全性最佳實踐

風險對策
Cookie 竊取 (XSS)httponly=true 防 JS 讀取、secure=true 僅 HTTPS 傳輸
Cookie 偽造/竄改敏感資料**不可直接存 Cookie**,改存 Session ID,資料放伺服器端 Session/資料庫
CSRF 攻擊表單加入 CSRF Token、SameSite=Strict/Lax (PHP 7.3+ setcookie 第 8 參數)
資訊洩漏範例中 Cookie 含明文 Email、姓名,**生產環境嚴禁**
編碼問題值含特殊字元需 urlencode() / urldecode() (PHP 自動處理)

現代化架構:Session + Cookie 分工

// 登入驗證成功後
session_regenerate_id(true); // 防 Session Fixation
$_SESSION['user_id'] = $userId;
$_SESSION['last_active'] = time();

// Cookie 僅存 Session ID (PHPSESSID),預設 httponly+secure
// 可自訂 Cookie 參數
session_set_cookie_params([
    'lifetime' => 3600,
    'path' => '/',
    'domain' => '.example.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax'
]);
session_start();

Cookie 相關陣列比較

陣列來源用途
$_COOKIEHTTP Request Cookie: 標頭讀取瀏覽器送來的 Cookie
$_SESSION伺服器端 Session 儲存 (檔案/資料庫/Redis)伺服器端狀態,安全、容量大
setcookie()HTTP Response Set-Cookie: 標頭寫入/更新/刪除 Cookie

總結

Cookie 是 HTTP 無狀態協議下維持狀態的基石。PHP 提供便利的 $_COOKIE 讀取與 setcookie() 寫入,**但切記:Cookie 完全由客戶端控制,不可信任**。敏感資料、權限判斷、業務關鍵邏輯必須放在伺服器端 Session 或資料庫,Cookie 僅作為識別鍵 (Session ID) 或非敏感偏好設定儲存。

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