ThinkPHP 5 不支持多应用,仅支持多模块;需开启 url_domain_deploy 才能启用域名绑定,Route::domain() 或 domain 数组绑定的必须是合法模块名(如 admin),且主域名须显式配置,否则未匹配域名将导致404。

ThinkPHP 5 不支持“多应用”概念,所谓“绑定不同应用”是误用术语——TP5 只有“多模块”,没有 app/admin/ 这类物理隔离的多应用目录结构。你真正能做的,是把不同域名绑定到不同模块(如 admin、api、mobile),每个模块共享同一套 app/ 目录下的核心结构。
必须开启 url_domain_deploy 才能识别域名
TP5 的域名绑定功能默认关闭,不配这个就根本不会解析 HTTP_HOST。在 config/app.php 里加这一行:
'url_domain_deploy' => true,
注意:APP_SUB_DOMAIN_DEPLOY 是 TP3/TP5 早期版本的旧配置,TP5.1+ 已弃用,写了也无效。如果没开这个,后面所有 Route::domain() 都不会触发。
Route::domain() 绑定的是模块名,不是目录路径
你在 route.php 里写的值,比如 'admin',指的是 app/module_name/ 下的模块名,不是任意目录。TP5 模块必须严格落在 app/ 下,且命名需小写、无符号、符合 PSR-4 命名规范。
立即学习“PHP免费学习笔记(深入)”;
- 正确:模块目录是
app/admin/,绑定写Route::domain('admin.example.com', 'admin') - 错误:模块目录是
app/Admin/(首字母大写)或app/api-v1/(含短横线),框架直接抛出InvalidArgumentException - 错误:绑成
'admin/example'或'app/admin'—— 值只能是模块名字符串,不能带斜杠
绑定后,控制器自动走 app/admin/controller/,命名空间是 app\admin\controller,视图路径是 app/admin/view/,这些都由框架内部推导,你不用手动改 config/template.php。
主域名(如 example.com)必须显式绑定,不能靠 fallback
TP5 不会自动把没匹配的域名扔给默认模块。如果你只写了:
Route::domain('admin.example.com', 'admin');<br>Route::domain('api.example.com', 'api');
那访问 example.com 或 www.example.com 时,路由层压根不进 Route::domain() 分支,而是走普通 URL 解析,结果大概率 404 或进错模块。
必须补上通配或显式主域名绑定:
- 方式一(推荐):绑定完整主域名
Route::domain('example.com', 'index'); - 方式二:用通配符
Route::domain('*', 'index');,但注意它会覆盖所有未声明的子域名,包括你未来可能加的test.example.com - 方式三:在
__domain__配置数组里统一写(见下条)
优先用 __domain__ 配置数组,别全靠 Route::domain() 动态注册
TP5 支持两种写法:动态调用 Route::domain(),或在 route.php 返回数组里用 '__domain__' 键集中配置。后者更稳定,尤其在 CLI 环境或某些中间件提前加载场景下,动态注册可能被跳过。
正确写法示例(route.php):
<?php<br>use think\Route;<br><br>return [<br> '__domain__' => [<br> 'admin.example.com' => 'admin',<br> 'api.example.com' => 'api',<br> 'example.com' => 'index',<br> 'www.example.com' => 'index',<br> ],<br>];
注意:'__domain__' 是顶层键,不是 Route::domain() 的参数;数组键必须是完整域名(含 .com),不能只写 'admin';值仍是模块名,不是路径。
容易踩的坑:__domain__ 数组必须放在 route.php 的 return 语句里,不能写在文件末尾裸 echo 或 dump;若用了 return 之后还有代码,会导致解析失败。
复杂点在于:TP5 的模块间无法完全隔离配置和中间件——所有模块共用 config/ 下的全局配置,中间件也按全局顺序加载。如果你需要数据库、缓存、日志等彻底分离,TP5 本身做不到,得升到 TP6+ 多应用模式,或者自己在模块入口手动切换配置。



















