domain_bind 是 ThinkPHP 5 中实现多域名绑定模块的唯一可靠方式,需在 config/app.php 中配置完整域名映射模块名,并在入口文件启用 APP_SUB_DOMAIN_DEPLOY=true。

domain_bind 配置在 ThinkPHP 5 中是唯一能实现「访问 a.com 自动进 admin 模块、b.com 自动进 api 模块」的可靠方式;写在 route.php 里的 Route::domain() 只影响路由匹配,不切换模块上下文,不能替代它。
domain_bind 必须写在 config/app.php 里,且值为模块名
ThinkPHP 5 的域名绑定模块逻辑由框架启动时读取 config/app.php 中的 domain_bind 数组驱动。它不是运行时规则,而是一次性映射表。
-
domain_bind键必须是完整域名(如'admin.example.com'),不能带协议或端口('https://admin.example.com'或'admin.example.com:8080'会失效) - 值必须是已存在的模块名(如
'admin'),对应application/admin/目录,不是控制器或命名空间 - 若模块目录不存在,或命名不一致(比如配置了
'Admin'但目录叫admin),请求会 fallback 到默认模块,且无明确报错 - 开发环境用
localhost测试?必须显式写成'localhost' => 'admin',不能省略
APP_SUB_DOMAIN_DEPLOY 要设为 true,否则 domain_bind 不生效
APP_SUB_DOMAIN_DEPLOY 是 TP5 启用域名部署的总开关,它控制框架是否解析 $_SERVER['HTTP_HOST'] 并查表匹配 domain_bind。这个配置不在 config/app.php 里,而是在入口文件(通常是 public/index.php)中定义。
- 必须在
require __DIR__ . '/../vendor/autoload.php';之前设置:define('APP_SUB_DOMAIN_DEPLOY', true); - 如果漏掉这行,哪怕
domain_bind写得再全,框架也完全无视 Host 头,一律走默认模块 - 注意:TP6+ 已废弃该常量,改用
url_domain_deploy配置项;TP5 不认这个,只认APP_SUB_DOMAIN_DEPLOY - Apache/Nginx 必须确保
HTTP_HOST被正确传递——部分虚拟主机或反向代理会过滤或重写它,可用dump($_SERVER['HTTP_HOST']);确认
模块内路由和视图路径自动适配,但 database.php 不自动切换
启用 domain_bind 后,TP5 会自动切换模块级上下文:控制器命名空间变成 app\module_name\controller,视图路径指向 application/module_name/view/,中间件也从对应模块加载。但数据库配置是个例外。
-
database.php默认只读根目录下的application/database.php,不会按模块查找application/admin/database.php - 若需不同模块连不同库,得在模块的公共文件(如
application/admin/common.php)中手动调用Config::set()覆盖数据库配置 - 模板继承、语言包、缓存前缀等都随模块隔离,无需额外操作
- URL 生成函数
url()默认不带域名,要输出完整链接得传参:url('index/index', [], true, 'https://admin.example.com')
APP_SUB_DOMAIN_DEPLOY 缺失和 HTTP_HOST 被代理截断——这两点不解决,其他配置全白搭。



















