📘 ThinkPHP 6 多应用与 `app_express` 详解:别再被“模块”和“应用”搞混了!

79 阅读3分钟

一、背景:从 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 到默认应用”。

🔍 执行流程(简化版):

  1. 用户访问 /aB3kL9xQ2m/user/index

  2. 框架取第一段:aB3kL9xQ2m

  3. 查 app_map → 映射为 admin

  4. 检查目录 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 就安全了”❌ 只要应用目录存在,依然可通过映射访问
“必须用多应用才能做前后台”❌ 单应用 + 路由分组 + 中间件更简单高效