You need to enable JavaScript to run this app. 如何在Laravel(OctoberCMS)查询中设置字段自增?为何自增量为预期值2倍?
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel(OctoberCMS)查询中设置字段自增?为何自增量为预期值2倍?

固定双倍增量的成因

首先要明确:increment()方法是基于单条原子SQL实现的字段自增,单次调用只会执行一次UPDATE 表名 SET 字段值 = 字段值 + 增量 WHERE 条件,不存在自动重复执行的机制。固定出现“传1加2、传2加4”的2倍增量,本质就是onStart()钩子被同一次页面请求重复触发了2次,常见的触发场景集中在几个易忽略的点:

  • 布局与页面的钩子重复挂载:OctoberCMS的渲染流程中,布局的onStart()逻辑会先于页面本身的onStart()逻辑执行,如果不小心在布局文件和页面文件里都写了相同的访客统计代码,就会在同一次请求里连续执行两次increment,刚好凑出2倍的增量。
  • URL规则的自动重定向触发:如果站点配置了尾部斜杠自动重定向、或者HTTPS/HTTP自动跳转规则,用户感知不到的301/302跳转也会产生两次独立的路由请求,两次请求都会匹配到同一个页面,各执行一次自增逻辑。
  • 路由匹配的兜底规则覆盖:如果配置了过于宽泛的通用路由,浏览器发起的无关资源请求(比如favicon探测、资源预取请求)被错误匹配到了当前内容页的路由规则,也会额外触发一次页面钩子的执行。
正确实现自增逻辑的方案

第一步:先定位重复触发的根源

在onStart()中加入请求日志,记录每次触发的上下文,就能快速定位重复原因:

function onStart(){
    \Log::info('访客统计逻辑触发', [
        '请求地址' => request()->fullUrl(),
        '请求参数' => request()->all(),
        '路由参数slug' => $this->param('slug'),
        '触发时间' => microtime(true)
    ]);
    ModelName::where('slug', '=', $this->param('slug'))->increment('visitors');
}

刷新一次页面后查看日志,如果看到两条触发记录,就顺着记录里的请求信息排查上面提到的几个常见重复点即可。

第二步:加请求级防重复加固

哪怕排查完所有重复触发的场景,也可以加一层兜底逻辑,避免同一次请求内的钩子重复执行导致计数异常:

function onStart(){
    $slug = $this->param('slug');
    // 使用array缓存驱动做单次请求内的标记,请求结束后自动清空
    $requestCache = \Cache::store('array');
    if (!$requestCache->has("visitor_increment_{$slug}")) {
        ModelName::where('slug', '=', $slug)->increment('visitors');
        $requestCache->put("visitor_increment_{$slug}", true);
    }
}

这种方式不需要修改现有路由或者配置,就能从逻辑上保证同一次请求不管触发多少次onStart(),都只会执行一次自增操作。

可选:优化统计逻辑避免刷新刷量

如果要避免用户频繁刷新页面导致的虚高计数,可以加基于用户会话的短时间锁定逻辑,同一个用户访问同一条内容,在设定的时间窗口内只计一次数:

function onStart(){
    $slug = $this->param('slug');
    $lockKey = "visitor_count_{$slug}_" . session()->getId();
    // 同一个用户1分钟内重复访问不重复计数
    if (!\Cache::has($lockKey)) {
        ModelName::where('slug', '=', $slug)->increment('visitors');
        \Cache::put($lockKey, true, now()->addMinute());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 02:15:03