You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP Laravel中有效记录页面浏览量?附现有实现咨询

嘿,你的基础实现方向没问题,但咱们可以从细节优化和架构层面入手,让浏览量记录更高效、健壮。先给你现有代码的调整建议,再聊聊更优的实现思路:

现有实现的优化指导

你的record_user_click函数已经具备了核心功能,但有几个细节可以完善:

  • 处理未登录用户:Auth::id()在用户未登录时会返回null,可以给字段设置默认值或者记录游客的会话ID,避免插入空值:
    $userId = Auth::check() ? Auth::id() : session()->getId();
    // 如果不需要会话ID,也可以直接设为null,记得确保数据库user_id字段允许空值
    
  • 避免重复无效记录:如果用户短时间内多次刷新同一页面,没必要重复插入记录。可以加个缓存判断,比如1分钟内同一用户(或会话)访问同一type+item_id不重复记录:
    $cacheKey = "click_{$userId}_{$type}_{$item_id}";
    if (!Cache::has($cacheKey)) {
        \DB::table('click_statistics')->insert([
            'user_id' => $userId,
            'type' => $type,
            'item_id' => $item_id,
            'referer' => $referer,
            'created_at' => now()
        ]);
        Cache::put($cacheKey, true, 60); // 缓存1分钟,避免重复触发
    }
    
  • 改用Eloquent模型:创建ClickStatistic模型代替直接用DB门面,代码会更易维护,还能利用Eloquent的事件、关联等扩展功能:
    // 先执行命令生成模型:php artisan make:model ClickStatistic
    ClickStatistic::create([
        'user_id' => $userId,
        'type' => $type,
        'item_id' => $item_id,
        'referer' => $referer
    ]);
    
更高效的浏览量记录方案

如果你的网站流量较大,直接同步写入数据库会增加数据库压力,推荐下面几种进阶方案:

  • 队列异步写入:把记录操作放到队列中,前台响应更快,后台异步处理写入逻辑,避免阻塞用户请求:
    // 先创建任务类:php artisan make:job RecordClick
    // 在RecordClick的handle方法中实现写入逻辑,然后在控制器里调用:
    RecordClick::dispatch($userId, $type, $item_id, $referer);
    
  • 中间件自动记录:如果多个页面都需要记录浏览量,可以写个路由中间件,自动识别请求的资源类型和ID,不用在每个控制器手动调用函数:
    // 生成中间件:php artisan make:middleware RecordPageView
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);
        // 只记录GET请求,避免POST/PUT等操作误触发
        if ($request->isMethod('get')) {
            // 根据路由参数获取资源信息,比如路由是 /products/{id}
            $type = 'product';
            $item_id = $request->route('id');
            $userId = Auth::check() ? Auth::id() : session()->getId();
            $referer = $request->header('referer', 'direct_access');
            // 用队列异步处理记录
            RecordClick::dispatch($userId, $type, $item_id, $referer);
        }
        return $response;
    }
    
  • 缓存聚合统计:对于高流量页面,可以先把浏览量存在Redis缓存中累加,定时同步到数据库,大幅减少数据库写入次数:
    // 记录时先累加缓存
    $cacheKey = "page_view_{$type}_{$item_id}";
    Redis::incr($cacheKey);
    
    // 在app/Console/Kernel.php中添加定时调度,每小时同步一次
    $schedule->call(function () {
        // 示例:同步所有商品的浏览量统计
        $productIds = Product::pluck('id');
        foreach ($productIds as $id) {
            $count = Redis::get("page_view_product_{$id}");
            if ($count) {
                Product::where('id', $id)->increment('view_count', $count);
                Redis::del("page_view_product_{$id}");
            }
        }
    })->hourly();
    

最后提醒下,根据你的业务规模选合适的方案就行:小流量网站优化现有代码足够,高流量场景优先考虑队列+缓存聚合的组合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:15:56