本地测试请求不触发限流统计,因默认使用客户端ip(如127.0.0.1)作为缓存key,而中间件常排除本地ip、代理未配置或路由解析不一致;可通过伪造x-forwarded-for头、开启trust_proxy、统一route标准化及直查redis验证。

本地测试请求不会被统计进限流数据——因为默认的 throttle 中间件和你手动写的 Cache::inc() 都依赖真实客户端 IP,而本地环境(127.0.0.1 或 ::1)常被 Nginx/Apache/PHP 透传为不可靠来源,或直接被缓存 key 排除。
为什么本地 curl 测试不触发统计?
常见现象:你在命令行执行 curl -v http://localhost/api/user,但 Redis 里查不到 api:rate:127.0.0.1:/api/user 这类 key。
- ThinkPHP 默认从
$request->ip()取 IP,而本地开发时该值常为127.0.0.1,部分中间件逻辑会跳过对该 IP 的计数(尤其开启了代理识别但未配TRUSTED_PROXY) -
Cache::inc()调用前可能加了条件判断,比如if (!in_array($ip, ['127.0.0.1', '::1'])) { ... },这是人为排除,不是框架默认行为 - 你用的是
php think run内置服务器,它不解析X-Forwarded-For,$request->ip()永远是127.0.0.1,无法模拟多 IP 场景 - Redis 缓存 key 拼接用了
$route,但本地测试时若带 query(如/api/user?id=1),而你的标准化逻辑又没覆盖php think run环境下的 pathinfo 解析,导致 key 不一致
如何让本地测试也能进统计?
目标:让 curl 请求走通完整统计链路,且 key 可查、数值可验证。
- 强制指定测试 IP:在请求头里加
-H "X-Forwarded-For: 192.168.1.100",并确保配置已开启代理识别:'trust_proxy' => true和'proxy_ip' => '127.0.0.1'(写在config/app.php) - 绕过 IP 判断:临时注释或修改中间件中对
127.0.0.1的过滤逻辑,例如把if ($ip === '127.0.0.1') return;改成if (false && $ip === '127.0.0.1') return; - 统一 route 标准化:在统计逻辑开头加调试输出,确认
$route = parse_url($request->url(), PHP_URL_PATH)或更稳妥的$request->rule()->getName(),避免 query 干扰 - 手动触发一次计数验证:在 Tinker 或命令行里执行
Cache::inc('api:rate:192.168.1.100:/api/user', 1),再查Cache::get('api:rate:192.168.1.100:/api/user'),确认缓存层工作正常
怎么验证统计逻辑真正在跑?
别只看前端图表或接口返回,要直连数据源头。
- 用
redis-cli手动扫描:运行redis-cli --scan --pattern "api:rate:*",确认有匹配 key 出现 - 检查 TTL:对任意一个 key 执行
TTL api:rate:192.168.1.100:/api/user,应返回 60 左右(非 -2 或 -1) - 观察递增原子性:连续发两次
curl -H "X-Forwarded-For: 192.168.1.100" http://localhost/api/user,然后GET api:rate:192.168.1.100:/api/user,结果应为"2",不是"1" - 注意
Cache::inc()返回值是递增后的整数,可在中间件里Log::info('count after inc', ['key' => $key, 'val' => Cache::inc($key, 1)])快速定位是否执行到这一步
真正容易被忽略的是 route 标准化时机——它必须在所有中间件(包括路由解析)完成后才稳定,过早取 $request->url() 会包含 query,过晚则可能被重定向改写。最稳的位置是在 app/middleware/RateLimitMiddleware.php 的 handle() 开头,且紧挨着 $route = $request->rule() ? $request->rule()->getRule() : '/'; 这类调用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











