ThinkPHP 6.0 多应用需扩展、目录、命名空间、路由四者严格对齐:必须安装think-multi-app扩展,删除app/controller目录,应用名与命名空间小写且一致,子应用路由需显式import,配置通过app/[name]/config目录覆盖全局。

ThinkPHP 6.0 多应用不是改个配置就能跑通的模式,它依赖扩展、目录结构、命名空间和路由加载四者严格对齐;缺一环,App not exists 或 Class not found 就会立刻报给你看。
必须先装扩展并清理旧结构
TP6.0 默认不带多应用能力,topthink/think-multi-app 是硬性前置依赖。不装它,哪怕目录建得再标准,框架也只认单应用。
- 在项目根目录执行:
composer require topthink/think-multi-app - 删掉
app/controller目录(及其下的Index.php等)——只要这个目录存在,框架就强制降级为单应用模式,app_multi_module => true也无效 - 确认
config/app.php中已启用:'app_multi_module' => true;若用的是较新版本(6.0.2+),auto_multi_app配置项已废弃,不用管
应用目录名和命名空间必须小写且无符号
应用名直接参与 URL 解析、自动加载和命名空间拼接,大小写或符号错误会导致路由 404 或类加载失败。
- 应用目录必须建在
app/下,如app/admin、app/api,不能是app/Admin或app/user-v2 - 控制器类命名空间必须匹配:例如
app/admin/controller/Index.php的类必须声明为namespace app\admin\controller;,不能是app\Admin\controller或app\controller - 模板默认路径为
view/[应用名]/,比如app/admin的视图文件得放在view/admin/下,否则fetch()找不到
路由必须显式 import,不能靠自动发现
route/route.php 是全局入口,但子应用的路由文件不会自动加载——不手动 import,app/admin/route.php 就是死文件。
立即学习“PHP免费学习笔记(深入)”;
- 在
route/route.php中写:Route::import('admin', 'admin')—— 第二个参数'admin'必须与app/admin目录名完全一致(大小写敏感) - 第一个参数
'admin'是路由分组标识,会影响生成的 URL 前缀;若写成Route::group('admin', ...)在子应用内再套一层,URL 会变成/admin/admin/index,纯属冗余 - 每个子应用的
route.php文件需独立定义逻辑,例如app/admin/route.php里不要写Route::get('index', ...),而应写Route::get('dashboard', 'Index/dashboard'),避免和主路由冲突
配置隔离靠目录优先级,不是靠开关
ThinkPHP 的配置合并机制是「应用级覆盖全局」,不是「开关式启用」。想让 admin 用独立数据库,关键不是打开某个 flag,而是把配置文件放对位置。
- 全局配置在
config/database.php,应用级配置放在app/admin/config/database.php,后者内容会自动合并覆盖前者同名键 -
app/admin/config/下的文件优先级高于config/,但低于环境变量(.env);调试时建议先确认.env没有意外覆盖 - 运行时目录也要隔离:
runtime/admin/和runtime/api/需手动设置,否则日志、缓存、模板编译全挤在一起,跨应用污染极易发生
最易被忽略的一点:CLI 命令默认仍作用于全局 app/controller,生成 admin 控制器要用 php think make:controller admin/Test --app=admin,漏掉 --app 参数,代码就建错地方了。



















