一、背景:从 TP5 的“多模块”到 TP6 的“多应用”
很多从 ThinkPHP 5 转到 TP6 的开发者会疑惑:
“TP6 的多应用是不是就是把 TP5 的‘模块’改名叫‘应用’?URL 都是
/xxx/控制器/方法,看起来一样啊。”
表面上看确实很像,但底层逻辑完全不同!
- TP5 多模块:同一个应用内划分功能区(如 admin/home),共享配置、中间件、数据库。
- TP6 多应用:每个“应用”是一个相对独立的子系统,可拥有自己的配置、路由、中间件、日志等。
💡 简单比喻:
- TP5 模块 = 一栋楼里的不同房间(共用水电)
- TP6 应用 = 同一个小区里的不同别墅(各自水电独立)
二、开启多应用的前提
TP6 默认是单应用。要使用多应用,必须安装官方扩展:
composer require topthink/think-multi-app
安装后,框架会自动注册中间件 \think\middleware\MultiApp,负责解析 URL 中的“应用名”。
三、关键配置项说明
1. default_app:默认应用
'default_app' => 'home'
当无法识别应用时(比如直接访问 /login),会 fallback 到这个应用(前提是开启了相关机制,见下文)。
2. app_map:应用别名映射
'app_map' => [
'aB3kL9xQ2m' => 'admin'
]
允许你用简短或加密的路径访问后台,例如:
https://example.com/aB3kL9xQ2m/user/index → 实际访问 app/admin/controller/User.php
3. app_express:单应用快速模式
'app_express' => true
这是最容易被误解的配置!很多人以为它“禁用多应用”,其实不是。
四、app_express => true 的真实作用(重点!)
✅ 正确理解:
app_express不是“禁用多应用”,而是“当 URL 第一段不是合法应用时,自动 fallback 到默认应用”。
🔍 执行流程(简化版):
-
用户访问
/aB3kL9xQ2m/user/index -
框架取第一段:
aB3kL9xQ2m -
查
app_map→ 映射为admin -
检查目录
app/admin/是否存在?-
✅ 存在 → 切换到
admin应用,继续处理/user/index -
❌ 不存在 → 才去看
app_express- 如果
app_express => true→ 使用default_app(如home) - 否则 → 报错 “应用不存在”
- 如果
-
🎯 关键结论:
| URL 示例 | 是否受 app_express => true 影响? |
|---|---|
/login/index | ✅ 是(因为 app/login 目录不存在,触发 fallback) |
/aB3kL9xQ2m/user | ❌ 否(因为映射后 admin 目录存在,直接进入) |
/admin/user | ❌ 否(同上) |
⚠️ 所以:只要目标应用目录存在,
app_express就不会阻止你访问它!
五、为什么我开了 app_express 还能访问后台?
因为你满足了以下条件:
- 配置了
'aB3kL9xQ2m' => 'admin' app/admin/目录真实存在- 框架在检查到
admin是合法应用后,直接切换上下文,根本没走到app_express分支
✅ 这是正常行为,不是 bug!
六、如何真正实现“纯单应用”?
如果你希望:
- 前台 URL 简洁:
/login、/index - 后台不能通过路径直接访问(除非走特定路由)
- 完全不需要“应用”概念
推荐做法:
✅ 方案一:卸载多应用扩展(最干净)
composer remove topthink/think-multi-app
-
所有请求都走
app/controller/... -
URL 直接是
/控制器/方法 -
后台用路由分组 + 中间件保护:
// route/app.php Route::group('admin', function () { Route::get('user', 'Admin/User/index'); })->middleware(AdminAuth::class);
✅ 方案二:保留多应用,但接受带应用名的 URL
- 前台:
/home/login - 后台:
/aB3kL9xQ2m/user - 适合需要强隔离的项目
❌ 不推荐:混合使用 app_express + app_map
容易造成逻辑混乱,且无法真正隐藏后台入口。
七、常见误区澄清
| 误区 | 正确认知 |
|---|---|
| “TP6 多应用 = TP5 多模块改名” | ❌ 架构完全不同,TP6 应用更独立 |
“app_express => true 会禁用多应用” | ❌ 只在无法识别应用时 fallback |
“开了 app_express 就安全了” | ❌ 只要应用目录存在,依然可通过映射访问 |
| “必须用多应用才能做前后台” | ❌ 单应用 + 路由分组 + 中间件更简单高效 |