中间件不调用 $next 就会静默中断请求,php中间件不是“自动往下走”的流程,而是完全由你控制是否继续;漏掉 $next->handle($request) 或 $next($request),请求就停在那里,既不报错也不进控制器。

中间件不调用 $next 就会静默中断请求
PHP中间件不是“自动往下走”的流程,而是完全由你控制是否继续。漏掉 $next->handle($request) 或 $next($request),请求就停在那里,既不报错也不进控制器——常见于鉴权失败后忘记 return 响应,结果页面白屏或返回 500。
- PSR-15 中间件必须显式调用
$handler->handle($request),否则链断裂 - 闭包式中间件(如 FrankenPHP 或手写 pipe)必须调用
$next($request),且要确保它被 return - ThinkPHP 6/8 中直接写
return response(...)即可中断,但不能用exit或die,否则跳过框架响应生命周期 - 调试时可在中间件开头加
error_log('hit: ' . __FILE__),确认是否真被执行
拦截 Host、Referer、IP 这三类请求头必须前置注册
想在路由解析前拦住非法请求,中间件必须放在全局数组最前面。比如 app/middleware.php 里,CheckHost::class 得排第一,否则请求已匹配到路由、甚至执行了 DB 查询才被拦,失去意义。
-
$request->header('host')要兼容代理环境,建议 fallback 到$request->host() - 白名单需含端口(如
localhost:8000),开发环境漏写端口会导致本地访问 403 - Referer 校验慎用
abort(403):它触发异常处理,保留日志;而response('', 403)不走异常流程,适合纯拦截 - IP 黑名单查缓存时,用
$request->ip(true)才能正确识别X-Forwarded-For,否则总拿127.0.0.1
修改响应 Body 或 Header 必须返回新 Response 实例
PHP 的 PSR-7/PSR-17 规范要求 Request 和 Response 是不可变对象。直接改 $response->getBody()->write(...) 不生效,必须用 withBody()、withHeader() 等方法返回副本。
- 注入 CORS 头:return
$response->withHeader('Access-Control-Allow-Origin', '*') - JSON 包装响应:return
json(['data' => $body, 'code' => 0])(TP 内置函数)或 newJsonResponse($data) - 缓存中间件中生成 key 时,别只拼
$request->getUri()->getPath(),得包含 query string 和 method,否则 GET /api?x=1 和 /api?x=2 缓存冲突 - FrankenPHP 中修改响应需在
frankenphp_handle_request()回调的后半段操作,不能在$next()之前改
Mock 数据中间件只应在 debug 模式下启用
开发阶段用中间件返回假数据很高效,但极易误发到生产环境。必须双重开关:配置项 + 环境变量,缺一不可。
- 检查
env('APP_DEBUG')和config('mock.enabled')同时为 true 才执行拦截逻辑 - 路径匹配优先用
$request->url()(含域名),比$request->path()更准,避免同路径不同子域漏判 - 返回 JSON 时手动设 header:
response()->json([...])->header('Content-Type', 'application/json'),否则前端fetch().json()报错 - 不要在中间件里调
Route::rule()—— 此时路由尚未解析,会返回 null 或抛异常
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











