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

PHP 購物車類實現:基於 Cookie 的輕量級方案(含增刪改查)

     編輯:PHP 相關知識

針對「僅需記錄商品類型與編號、不涉及數量」的簡易購物車場景,本文提供一個基於 Cookie 的純 PHP 實現。代碼結構清晰,支援新增、查詢、刪除、清空操作,適合中小型專案快速整合或作為教學參考。注意:Cookie 容量限制 4KB,商品數量較大時建議改用 Session + 資料庫方案。

資料結構設計

Cookie 值格式:type1:id1,id2|type2:id3,id4|type3:id5

  • 類型之間用 | 分隔
  • 類型與 ID 列表用 : 分隔
  • 同類型下多個 ID 用 , 分隔

核心類代碼

<?php
class Cart
{
    private const COOKIE_NAME = 'cart';
    private const COOKIE_EXPIRE = 86400 * 30; // 30 天

    /**
     * 新增商品到購物車
     * @param string $type 商品類型
     * @param string|int $id 商品編號
     */
    public function add(string $type, $id): void
    {
        $cartStr = $_COOKIE[self::COOKIE_NAME] ?? '';

        if ($cartStr === '') {
            // 首次新增
            $cartStr = "{$type}:{$id}";
        } else {
            $typeExists = false;
            $parts = explode('|', $cartStr);

            foreach ($parts as $i => $part) {
                [$existingType, $idList] = explode(':', $part, 2);
                if ($existingType === $type) {
                    $typeExists = true;
                    $ids = explode(',', $idList);
                    if (!in_array((string)$id, $ids, true)) {
                        $ids[] = (string)$id;
                        $parts[$i] = $type . ':' . implode(',', $ids);
                    }
                    break;
                }
            }

            if (!$typeExists) {
                $parts[] = "{$type}:{$id}";
            }
            $cartStr = implode('|', $parts);
        }

        setcookie(self::COOKIE_NAME, $cartStr, time() + self::COOKIE_EXPIRE, '/');
    }

    /**
     * 獲取指定類型的商品 ID 列表
     * @return array 數字索引陣列,不存在返回空陣列
     */
    public function getIds(string $type): array
    {
        $cartStr = $_COOKIE[self::COOKIE_NAME] ?? '';
        if ($cartStr === '') return [];

        $pattern = '/' . preg_quote($type, '/') . ':([^|]+)/';
        if (preg_match($pattern, $cartStr, $matches)) {
            return explode(',', $matches[1]);
        }
        return [];
    }

    /**
     * 刪除指定類型下的某個商品 ID
     */
    public function remove(string $type, $id): void
    {
        $cartStr = $_COOKIE[self::COOKIE_NAME] ?? '';
        if ($cartStr === '') return;

        $parts = explode('|', $cartStr);
        $newParts = [];

        foreach ($parts as $part) {
            [$existingType, $idList] = explode(':', $part, 2);
            if ($existingType !== $type) {
                $newParts[] = $part;
                continue;
            }

            $ids = explode(',', $idList);
            $ids = array_filter($ids, fn($v) => $v !== (string)$id);

            if (!empty($ids)) {
                $newParts[] = $type . ':' . implode(',', $ids);
            }
            // 若該類型無剩餘 ID,直接不加入 newParts(相當於刪除該類型)
        }

        $newCartStr = implode('|', $newParts);
        setcookie(self::COOKIE_NAME, $newCartStr, time() + self::COOKIE_EXPIRE, '/');
    }

    /**
     * 清空購物車
     */
    public function clear(): void
    {
        setcookie(self::COOKIE_NAME, '', time() - 3600, '/');
    }

    /**
     * 獲取完整購物車結構(用於調試/前端渲染)
     * @return array ['type' => ['id1', 'id2', ...], ...]
     */
    public function all(): array
    {
        $cartStr = $_COOKIE[self::COOKIE_NAME] ?? '';
        if ($cartStr === '') return [];

        $result = [];
        foreach (explode('|', $cartStr) as $part) {
            [$type, $idList] = explode(':', $part, 2);
            $result[$type] = explode(',', $idList);
        }
        return $result;
    }
}

使用範例

<?php
require_once 'Cart.php';
$cart = new Cart();

// 新增商品
$cart->add('food', 101);
$cart->add('food', 102);
$cart->add('drink', 201);

// 查詢
var_dump($cart->getIds('food'));  // ['101', '102']
var_dump($cart->all());

// 刪除單個商品
$cart->remove('food', 101);

// 清空
$cart->clear();

擴展建議

需求實現方向
支援商品數量ID 列表改為 id:qty 格式,或改用 JSON 結構 {type: {id: qty}}
突破 4KB 限制Cookie 僅存 cart_token,資料落地 Redis/資料庫,Key 為 token
多伺服器同步必須使用集中式存儲(Redis/DB),Cookie 僅作識別
防篡改簽名(HMAC)或加密(AES-GCM)Cookie 值

安全提醒

  • Cookie 可被用戶竄改,**切勿直接信任 Cookie 內容執行敏感操作**(如價格計算、庫存扣減)。
  • 下單前務必在後端重新驗證商品存在性、價格、庫存、用戶權限。
  • 設定 HttpOnly、Secure(HTTPS 環境)、SameSite=Lax 降低 XSS/CSRF 風險。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved