tp6+中app_init钩子已废弃,必须迁移到中间件并严格按请求生命周期顺序注册:依赖session的放sessioninit之后,切换语言的放loadlangpack之前,预处理请求体的需首个执行,且须清缓存。

ThinkPHP 的 app_init 钩子在 TP6+ 中已被废弃,必须迁移到中间件;迁移不是简单复制代码,而是要按请求生命周期重新组织逻辑,否则 Session、Lang、Request 参数等都可能读不到或失效。
为什么不能直接把 app_init 代码塞进中间件 handle()
因为 app_init 是框架启动早期的钩子,执行时 Request 和 App 实例尚未完全构建,而中间件的 handle() 方法运行在完整请求上下文中——但时机仍比 SessionInit、Lang 加载等中间件靠前。若你原 app_init 里写了 session('user') 或 lang('xxx'),直接搬进来会返回 null 或默认语言。
- Session 尚未初始化:此时调用
$request->session()->get()可能为空,得确认中间件注册顺序在\think\middleware\SessionInit::class之后 - 语言包未加载:若你在
app_init里调了Lang::setLang('en-us'),中间件里必须放在\think\middleware\LoadLangPack::class之前执行,且不能晚于 Cookie/Session 读取 - Request 参数未解析:
$request->param()在早期中间件中不可靠,应改用$request->get()、$request->post()或$request->getRawContent()显式取值
中间件替代 app_init 的正确注册位置
必须写进 app/middleware.php 全局中间件数组,并严格控制顺序:
- 需要访问 Session → 放在
\think\middleware\SessionInit::class之后 - 需要切换语言 → 放在
\think\middleware\LoadLangPack::class之前(否则设置无效) - 需要修改原始请求体(如解密、Trim)→ 必须是第一个中间件(索引 0),否则后续中间件已读过旧参数
- 示例顺序:
return [\app\middleware\AppInitCompat::class, \think\middleware\SessionInit::class, \think\middleware\LoadLangPack::class, ...];
AppInit 兼容中间件怎么写(含常见陷阱)
新建 app/middleware/AppInitCompat.php,继承 think\middleware\BaseMiddleware,重点处理三类典型逻辑:
- 环境/配置预设:可直接执行,如
Config::set('app.debug', true),无依赖问题 - 全局变量注入:用
Container::getInstance()->bind('my_service', MyService::class)替代原define()或$GLOBALS赋值 - 请求预处理(如加解密、参数清洗):必须用
$request->getRawContent()读原始流,处理完再$request->merge($data)刷新缓存;切勿在handle()里调$_POST或input()—— 此时它们还没被框架解析
关键细节:handle() 最后必须 return $next($request),不能漏;若需中断,返回 json(['code'=>500]) 等 Response 实例,别用 exit 或 die。
多应用模式下容易漏掉的点
如果你启用了 app/multi_app,app/middleware.php 是全局配置,对所有应用生效;但某些 app_init 逻辑只该跑在 admin 或 api 模块里。这时不能只靠全局中间件,得:
- 在对应模块目录下建
app/admin/middleware.php,单独返回该模块的中间件数组 - 把兼容中间件类挪到
app/admin/middleware/AppInitCompat.php,命名空间同步改为app\admin\middleware - 路由级绑定更精准:如
Route::group('admin', function () {...})->middleware(\app\admin\middleware\AppInitCompat::class);
最常被忽略的是:迁移后没清缓存,runtime 下的 cache 和 route 目录残留旧钩子注册信息,导致行为不一致——改完务必执行 php think clear。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











