電商、內容平台常需在用戶端記錄最近瀏覽的商品/文章,供「猜你喜歡」「最近瀏覽」展示。若用戶量大、記錄非核心數據,可直接利用 Cookie 客戶端存儲,無需佔用服務端存儲資源。
[['id'=>1,'name'=>'A'], ['id'=>2,'name'=>'B']],最新在前。array_unshift 插入隊頭。id 跳過。array_pop 移除最舊。<?php
class BrowseHistory {
const COOKIE_NAME = 'browse_history';
const MAX_ITEMS = 5;
const TTL = 2592000; // 30 天
/**
* 添加瀏覽記錄
* @param array $item 必須包含唯一標識鍵 'id'
*/
public static function add(array $item) {
if (empty($item['id'])) return false;
$history = self::get();
// 1. 去重:移除已存在的相同 id
$history = array_values(array_filter($history, function($v) use ($item) {
return $v['id'] != $item['id'];
}));
// 2. 新增到隊頭
array_unshift($history, $item);
// 3. 截取長度
if (count($history) > self::MAX_ITEMS) {
array_splice($history, self::MAX_ITEMS);
}
// 4. 寫入 Cookie
setcookie(self::COOKIE_NAME, serialize($history), time() + self::TTL, '/', '', true, true);
return true;
}
/**
* 獲取歷史記錄 (已反序列化)
* @return array
*/
public static function get() {
if (isset($_COOKIE[self::COOKIE_NAME])) {
$data = @unserialize($_COOKIE[self::COOKIE_NAME]);
if (is_array($data)) return $data;
}
return [];
}
/** 清空歷史 */
public static function clear() {
setcookie(self::COOKIE_NAME, '', time() - 3600, '/');
}
}
// --- 使用示例 ---
// 商品詳情頁控制器中
$product = ['id' => 1001, 'name' => 'iPhone 15', 'price' => 5999, 'img' => '...'];
BrowseHistory::add($product);
// 模板中展示
$history = BrowseHistory::get();
foreach ($history as $item) {
echo "<div>{$item['name']} - ¥{$item['price']}</div>";
}
?>
| 優點 | 缺點 |
|---|---|
| 零服務端存儲成本,橫向擴展無壓力 | Cookie 大小限制 4KB,只能存極少量數據 (約 20-50 條簡單記錄) |
| 用戶刪除 Cookie 即清空,隱私友好 | 用戶可禁用/清除 Cookie,數據不可靠 |
| 跨域共享方便 (設置 Domain) | 每次請求自動攜帶,增加帶寬開銷 |
| 實現極簡,無需引入 Redis/DB | 序列化/反序列化有性能開銷 (極微) |
hash_hmac('sha256', $serialized, $secret) 存入另一 Cookie 或拼接在值中,讀取時驗證。gzcompress + base64_encode 可減少 50%+ 體積,突破 4KB 限制。['id'=>1001],展示時通過 ID 批量查詢商品詳情 (緩存),避免 Cookie 存冗余字段。純前端方案:JS 將歷史存入 localStorage (5MB+),頁面加載時 JS 讀取渲染或調用 API 批量獲取詳情。後端完全無感,更適合前後端分離架構。