You need to enable JavaScript to run this app. Laravel 8实现商品最近浏览cookie存储:如何追加ID并去重
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8实现商品最近浏览cookie存储:如何追加ID并去重

Laravel 8 商品最近浏览Cookie功能实现方案

核心问题根源

  • 此前逻辑要么直接覆盖旧Cookie值,要么通过字符串拼接构造数据后多层JSON编码,导致转义混乱
  • 未全程使用PHP数组操作,最终存储的Cookie结构不符合预期的一维ID数组
  • 未做去重、条数限制处理

正确实现代码

1. 控制器(ProductController@show)逻辑

// 读取已存在的Cookie并解码为一维数组,不存在则初始化为空数组
$recentlyViewed = json_decode(request()->cookie('recently_viewed'), true) ?? [];

// 移除当前商品ID的旧记录(去重核心逻辑)
$recentlyViewed = array_diff($recentlyViewed, [$product->id]);

// 将当前商品ID加入数组(若需最新浏览排最前用array_unshift,排最后用array_push)
array_unshift($recentlyViewed, $product->id);

// 限制最多保存10条记录(避免Cookie超过4KB的浏览器限制)
$recentlyViewed = array_slice($recentlyViewed, 0, 10);

// 将一维数组编码为JSON字符串存入Cookie,过期时间单位为*分钟*
Cookie::queue(
    'recently_viewed',
    json_encode($recentlyViewed),
    1440 // 示例:1天(1440分钟),可按需调整
);

注意:Laravel默认加密所有Cookie,必须使用request()->cookie()或Cookie::get()读取,不能用原生$_COOKIE超全局变量。
测试提示:Laravel的Cookie::queue()会在当前响应完成时才将Cookie写入客户端,需刷新页面后才能看到Cookie值的更新,属于正常现象。

2. Blade模板渲染逻辑

@php
    // 读取Cookie并解码为一维数组,处理空值
    $recentlyViews = json_decode(Cookie::get('recently_viewed'), true) ?? [];
@endphp

{{-- 仅当存在浏览记录时渲染 --}}
@if (count($recentlyViews))
    <div class="recently-viewed-products">
        <h4>最近浏览的商品</h4>
        <ul>
            @foreach ($recentlyViews as $productId)
                {{-- 推荐先在控制器中批量查询商品(避免N+1问题),此处示例为简化 --}}
                @php($recentProduct = \App\Models\Product::find($productId))
                @if ($recentProduct)
                    <li>
                        <a href="{{ route('products.show', $recentProduct->id) }}">
                            {{ $recentProduct->name }}
                        </a>
                    </li>
                @endif
            @endforeach
        </ul>
    </div>
@endif

此时Cookie存储的格式完全符合需求,解码后为标准一维索引数组:

[
    0 => 4,
    1 => 1,
    2 => 5,
]

优化建议

  • 避免N+1查询:在控制器中批量查询ID对应的商品集合,而非Blade中循环单查:
// 控制器中,拿到$recentlyViewed数组后批量查询
$recentProducts = \App\Models\Product::whereIn('id', $recentlyViewed)->get();
// 将$recentProducts传递给Blade视图,直接循环该集合
  • 后续数据库同步:因Cookie存储的是干净的ID数组,后续可直接读取该数组,同步写入用户浏览历史表,无需处理转义或格式问题
  • 过期时间调整:若需长期保存,可将Cookie::queue()第三个参数设为10080(1周)或更长

内容的提问来源于stack exchange,提问作者Yousef Altaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.06 12:54:02