tp8多应用模式下中间件不生效的根本原因是app_multi未正确开启或配置错误:需显式设置'app_multi'=>true,子应用必须有独立middleware.php文件且格式严格,类路径与命名空间须完全匹配目录结构,否则框架静默跳过。

中间件在TP8多应用模式下根本没加载
TP8 默认关闭多应用隔离,app_multi 不显式开启,所有子应用(如 admin、api)的中间件都会被忽略——哪怕你把类文件放对了位置、命名空间也正确,框架压根不扫描子目录下的 middleware/ 文件夹。
验证方式:在 app/middleware.php 里加一行 Log::info('global middleware loaded');,请求后有日志;再在 app/admin/middleware/AuthCheck.php 的 handle() 开头加同样日志,若无输出,基本就是 app_multi 没生效。
- 确认
config/app.php中已设置'app_multi' => true,不能只写app_multi => true(缺引号会导致布尔值解析失败) - 子应用的中间件配置文件必须独立存在:
app/admin/middleware.php,内容格式与主应用一致:return [\app\admin\middleware\AuthCheck::class]; - TP8 不再兼容 TP6 的
data/route/route.php全局路由级中间件写法,子应用中间件必须走自己的middleware.php或路由定义时链式调用 - 若启用
app_multi后仍不生效,检查app/multi_app.php是否存在且返回应用列表数组,缺失该文件会导致子应用初始化中断,中间件注册流程直接跳过
app\_middleware.php 被当成普通PHP文件执行
TP8 在多应用模式下,会为每个子应用单独加载其 middleware.php,但该文件必须是纯配置脚本:不能含 use、不能有 echo、不能有 BOM 头、不能有任何非数组返回值。一旦出错,框架静默跳过,不会报错也不会警告。
- 用十六进制编辑器或
file -i app/admin/middleware.php检查是否含 UTF-8 BOM;若有,转为 UTF-8 without BOM - 删掉所有
use语句——即使类名带反斜杠也要写全:\app\admin\middleware\AuthCheck::class,而不是先use app\admin\middleware\AuthCheck;再写AuthCheck::class - 确保文件末尾没有空格、换行外的任何字符;首行不能是
<?php echo 'test';,必须严格以<?php return [...];开头 - TP8 下若返回数组中混入字符串类名(如
'app\admin\middleware\AuthCheck')而非::class常量,反射失败后中间件不触发,且无日志提示
中间件类路径与命名空间不匹配
TP8 强制要求「类名 = 文件名」+「命名空间 = 目录结构」,且不扫描子目录。比如 app/admin/middleware/auth/AuthCheck.php 这种路径,无论命名空间怎么写,框架都不会加载。
- 正确路径只能是:
app/admin/middleware/AuthCheck.php,对应命名空间app\admin\middleware - 生成命令仍可用:
php think make:middleware AuthCheck --app=admin,但需确认是否真生成到app/admin/middleware/下(某些旧版命令行工具会忽略--app参数) - 类定义必须实现接口:
use think\contract\MiddlewareInterface;+implements MiddlewareInterface,TP6 兼容写法在 TP8 下可能被加载但 handle() 不被调用 - 检查
composer.json的 autoload 配置:多应用模式下,若未为app/admin单独加 PSR-4 映射,composer dump-autoload后类仍无法自动加载
中间件执行了但鉴权逻辑没起作用
加载成功 ≠ 生效。TP8 中间件链顺序更敏感,尤其在多应用下,前置中间件(如 Session 初始化、路由绑定)未就位,后续中间件读不到 $request->rule() 或 $request->session() 就会直接跳过判断。
- 在
app/admin/middleware.php中,把\think\middleware\SessionInit::class放在自定义中间件之前;否则$request->session()返回 null - 不要在中间件构造函数里访问
$request或session(),此时上下文未注入;所有逻辑必须放在handle()内,且优先校验$request->rule() !== null - 若使用 JWT,
$request->header('Authorization')可能为空——因为跨域中间件(如AllowCrossDomain)若放在鉴权中间件之后,浏览器预检请求(OPTIONS)不会携带 Authorization,导致鉴权中间件被跳过 - TP8 中
$request->param()已缓存,但若前面有中间件调用了$request->getContent()或$request->input(),POST 数据流已被消耗,后续中间件取不到参数
app_multi 是开关,middleware.php 是入口,而类文件路径和命名空间是最后一道硬性门禁——三者缺一不可,且任意一个字符错,中间件就彻底隐身。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











