thinkphp二级域名绑定需先配置domain_bind数组实现域名到应用硬路由,再在各应用目录下独立配置database.php或模型层指定$connection,nginx须透传http_host头。

ThinkPHP 实现“二级域名绑定 + 每个域名连不同数据库”,不是简单叠加两个功能,而是分层协作:先靠 domain_bind 或 Route::domain() 实现域名到应用的硬路由,再在对应应用内独立配置数据库连接。不能指望一个全局 database.php 自动按域名切换库——框架不自动做这事,必须手动隔离。
一、先完成二级域名到应用的正确绑定
这是前提,没这步,后续数据库隔离无从谈起。
- 确保项目已启用多应用模式(如 app/admin/、app/api/ 目录存在),且 config/app.php 中开启:
'url_domain_deploy' => true - 在 config/app.php 的 domain_bind 数组中明确绑定完整域名与应用目录名:
['admin.example.com' => 'admin', 'api.example.com' => 'api']
注意:键必须是完整域名(含端口如 'localhost:8000'),值必须是 app/ 下真实存在的目录名 - 不要只依赖 Route::domain() —— 它只在 domain_bind 生效后才起作用;单独写 Route::domain('admin.example.com', ...) 不会切换应用上下文,控制器仍去 app/controller/ 找,必然报错
二、为每个应用独立配置数据库连接
绑定完成后,每个子域名请求进入对应应用(如 admin.example.com → app/admin/),此时应让该应用使用专属数据库配置,而非共用全局 config/database.php。
- 在 app/admin/config/database.php 中单独定义该应用的数据库配置(路径要对,文件需存在)
内容与根目录 config/database.php 结构一致,但只服务于 admin 应用 - 同理,app/api/config/database.php 配置 api 应用的数据库(如日志库、第三方同步库)
- 若不想复制多份 config 文件,也可在 app/admin/common.php 或中间件中动态调用:
Db::connect(['type'=>'mysql', 'hostname'=>'192.168.1.20', 'database'=>'admin_db', ...])
但注意:此方式需在每次查询前显式调用,不适合模型层统一管理
三、模型层强制绑定指定连接(推荐)
更稳定可控的方式是让每个应用下的模型主动指定连接名,避免环境误用。
- 在 app/admin/model/User.php 中设置:
protected $connection = 'mysql_admin'; - 同时,在 app/admin/config/database.php 的 connections 中定义:
'mysql_admin' => ['type'=>'mysql', 'hostname'=>'...', 'database'=>'admin_db'] - 这样,User::select() 就永远走 admin_db,不受其他应用或全局配置干扰
- 多个应用可共用同一份 connections 定义(放在根 config/database.php),但各模型通过 $connection 属性精准指向各自库
四、Nginx/Apache 必须透传 Host 头
本地开发或生产部署时,Web 服务器若未正确传递原始 Host,会导致 $_SERVER['HTTP_HOST'] 错误,domain_bind 匹配失败。
- Nginx 示例配置片段:
fastcgi_param HTTP_HOST $host;
不能漏掉这行,尤其在反向代理或 SSL 终止场景下 - Apache 需确认 VirtualHost 的 ServerName / ServerAlias 覆盖所有目标域名,并启用 UseCanonicalName Off
- 本地测试记得改 hosts 文件,把 admin.example.com 和 api.example.com 都指向 127.0.0.1
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











