不推荐默认开启多模块,TP6官方已将其定位为历史兼容特性;推荐单模块+多应用或领域分层+命名空间隔离,通过think-app命令创建平级应用,共享逻辑应使用Composer包或PSR-4本地扩展。

ThinkPHP 多模块目录划分是否还推荐?
不推荐默认开启多模块(APP_MULTI_MODULE = true)来组织大型项目。TP6 官方已明确将「多模块」定位为历史兼容特性,核心推荐方式是「单模块 + 多应用」或「领域分层 + 命名空间隔离」。强行用 app/模块名/ 结构会导致路由冲突、配置加载混乱、命令行工具(如 php think)识别异常,尤其在使用 Swoole 或 RoadRunner 时,模块自动加载极易引发类找不到错误。
TP6 中真正可行的模块化方案:应用级拆分
用 think-app 命令创建独立应用,而非手动建模块目录:
php think build:app admin php think build:app api php think build:app pay
每个应用拥有完整生命周期,可单独配置中间件、事件、数据库连接,且天然支持独立部署。关键点:
-
app/admin/和app/api/是平级应用,不是子目录模块 - 共用
config/下公共配置,但各自可覆盖app/admin/config/ - 路由定义在
app/admin/route/app.php,不会与app/api/route/app.php冲突 - 命令行需指定应用:
php think migrate:run --app=admin
模块间共享逻辑怎么处理?别放 app/common
TP6 已移除 app/common 全局目录。共享代码应通过 Composer 包或本地 PSR-4 扩展实现:
立即学习“PHP免费学习笔记(深入)”;
- 把通用服务抽成独立包,
composer require mycorp/core引入 - 若暂不发包,直接在
app/同级建src/目录,然后在composer.json中添加:"autoload": { "psr-4": { "Shared\": "src/" } } - 各应用内用
use SharedServicePaymentClient;调用,避免跨应用 include 或 require - 切勿在
app/admin/controller里直接include ../../api/service/Payment.php—— 类自动加载会失效,且 IDE 无法跳转
路由与中间件如何按模块收敛?
每个应用的路由必须严格限定作用域,不能依赖「模块名前缀」做隔离:
- 禁用全局
Route::domain()或Route::group(['prefix' => 'admin'])统一管理多模块路由 - 在
app/admin/route/app.php中只注册 admin 应用相关路由,并显式绑定中间件:Route::middleware('auth')->group(function () { ... }); - 中间件类需按应用命名空间存放,如
appdminmiddlewareAuth,避免多个应用共用同一个appmiddlewareAuth导致 session 或 guard 判断错乱 - API 应用若需 JWT 鉴权,应新建
apppimiddlewareJwtAuth,而不是复用后台的权限中间件
真正的难点不在目录怎么建,而在于「边界意识」——每个应用要像微服务一样有清晰的输入输出契约,数据库表前缀、缓存键命名、事件订阅范围都得提前对齐。目录结构只是表象,没想清楚职责划分,再多层嵌套也救不了耦合。



















