中间件不生效首要排查注册问题:确认app/middleware.php存在且返回带命名空间的类名数组,路由绑定必须显式调用middleware(),handle()方法每条分支均需return response实例。

中间件类没注册到请求链里
请求统计中间件不生效,第一反应不是逻辑写错了,而是它根本没进请求处理流程。ThinkPHP 6+ 的中间件必须显式注册,app/middleware.php 是全局中间件的唯一入口,但它只对「应用级」请求起作用——比如非路由分组、非资源路由兜底的请求。
常见错误包括:
- 删掉或重命名了
app/middleware.php,导致框架加载时返回null或解析失败 - 文件里写了
echo、var_dump或 BOM 头,PHP 解析中断,返回非数组 - 返回了空数组
[]、字符串"app\middleware\Stats"(没加反斜杠)或类名没带命名空间,如只写Stats::class而不是\app\middleware\Stats::class - 多应用模式下(如启用
app/multi_app),还在根目录app/middleware.php里注册,实际应放在app/admin/middleware.php并用\app\admin\middleware\Stats::class
路由绑定漏掉了 middleware() 链式调用
如果你的统计目标是某组 API 或后台接口,而不是全站所有请求,那靠 app/middleware.php 就不够用了。全局中间件默认不参与路由级细粒度控制,尤其像 Route::resource() 或闭包路由,必须手动挂载。
正确写法示例:
Route::group('api', function () {
Route::get('user/list', 'Api/UserController@list');
})->middleware(\app\middleware\Stats::class);
错误写法(完全无效):
Route::group('api', function () {
Route::get('user/list', 'Api/UserController@list');
});
// 没有 ->middleware(...),中间件压根不会执行
注意:资源路由 Route::resource('post', 'PostController') 不会继承控制器构造函数里的 $this->middleware(),每个动作(index/show/store)都得单独指定中间件,或改用分组绑定。
handle() 方法没 return Response 实例
这是最隐蔽也最致命的问题:中间件函数末尾没 return,PHP 默认返回 null,框架会当成「中断请求」处理,后续中间件和控制器全被跳过——你的统计代码可能执行了,但请求没往下走,数据就断在半路。
关键点:
-
handle($request, \Closure $next)签名必须严格匹配,不能少参数 - 放行必须写
return $next($request),不能只写$next($request) - 若要拦截(比如限流触发),得返回
json(['code' => 429])或abort(429),不能die或exit - 统计逻辑建议放在
$next($request)之后,这样能拿到真实响应耗时:$start = microtime(true); $response = $next($request); $cost = microtime(true) - $start;
统计数据写入失败或被覆盖
中间件里做统计,常犯的错是直接往文件/数据库里写,却忽略了并发、生命周期和存储可靠性。比如用 file_put_contents('stats.log', ... , FILE_APPEND) 在高并发下容易丢记录;用 Db::insert() 每次都连库,性能差还可能因事务未提交而丢失。
更稳妥的做法:
- 用
cache()->set('stats:today', $data, 3600)先存内存缓存,定时脚本汇总落库 - 若必须实时入库,改用
Db::execute("INSERT INTO stats (...) VALUES (...)"避免 ORM 开销 - 别在中间件里调
session()或cookie()函数——它们依赖后续中间件初始化,应改用$request->session()->get()或$request->cookie() - 跨域预检(OPTIONS)请求也会进中间件,但通常不需统计,开头加
if ($request->isOptions()) { return $next($request); }过滤掉
真正难调试的,往往不是“没写代码”,而是“写了但没进链”或“进了链但没 return”。盯住 app/middleware.php 是否存在、handle() 是否每条分支都有 return、路由定义是否真带 ->middleware()——这三处查完,八成问题就定位到了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











