Cache::inc()总返回false是因为默认File/Array驱动不支持原子自增,必须切换为Redis/Memcached驱动并验证连接;key需用归一化IP和路由名构造,限流逻辑须置于中间件$next()之前执行。

直接用 Cache::inc() 限流,90% 的人会在线上失效——因为默认文件驱动不支持原子操作,本地测通了,一上生产就漏判。
Cache::inc() 总返回 false 怎么办
这不是代码写错了,是缓存驱动没切对。File 和 Array 驱动压根没实现 inc() 方法,调用直接返回 false,不会报错也不会警告。
- 检查
config/cache.php中'default' => 'redis'是否生效,且'redis'配置块 host/port/password 全部可连通 - 别在开发环境用 File 驱动测试限流逻辑——它天生不支持并发安全,测出来也没参考价值
- 验证是否真可用:
Cache::store('redis')->inc('test_inc_key'),返回整数才算通;返回false就得先排查 Redis 连接或权限
限流 key 构造的三个致命坑
key 拼错,限流就等于没设。常见错误是拿完整 URL 或未归一化的 IP 直接拼接,导致同一用户/接口生成多个 key,计数分散失效。
- IP 必须归一化:
$request->ip(0, true)防代理头伪造;IPv6 要转成固定格式(如去掉冒号、补零) - 不要用
$request->url(),改用路由名:$request->rule()->getName()或手动定义标识如'api_login' - 敏感接口建议加时间分片:
'req_' . date('i') . '_' . $ip . '_' . $action,避免单 key 过热拖垮 Redis
中间件里限流响应被吞或乱序
TP6 中间件中 $next($request) 前后位置写反,会导致限流判断无效,或者响应头被覆盖、JSON 被污染。
立即学习“PHP免费学习笔记(深入)”;
- 限流逻辑必须在
$next($request)之前执行,否则业务已跑完,拦也拦不住 - 若需返回拦截响应(如 429),必须用
json()或response()->code(429)显式构造,不能只return数组 - 该中间件在
app/middleware.php中的注册顺序,要排在「响应格式处理类」(如 JSON 封装中间件)之前,否则响应头注入会失败
真正难的不是写几行 inc(),而是 key 的边界控制、驱动的实际行为、中间件执行时序这三者的咬合——漏掉任意一环,防刷就只剩心理安慰。



















