必须在入口文件public/index.php开头用$_server['http_host']手动switch切换bind_module和conf_path,否则配置无法按域名隔离;conf_path需在app::run()前定义,且config/app.php中default_module必须设为bind_module而非字符串。

ThinkPHP 5 无法靠 domain_bind 或路由层自动切换配置文件,必须手动在入口或初始化阶段读取 $_SERVER['HTTP_HOST'] 并加载对应配置 —— 这是唯一可靠方式。
入口文件中用 switch 切换 BIND_MODULE 和配置目录
TP5.1 不支持运行时切换应用上下文,所有模块/配置分流必须在 public/index.php 中完成。不能依赖中间件或路由回调,否则 default_module 已固化,后续加载的配置无效。
- 在
public/index.php开头立即判断域名,例如:switch ($_SERVER['HTTP_HOST']) { case 'admin.example.com': define('BIND_MODULE', 'admin'); define('CONF_PATH', APP_PATH . 'admin' . DS . 'config' . DS); break; case 'api.example.com': define('BIND_MODULE', 'api'); define('CONF_PATH', APP_PATH . 'api' . DS . 'config' . DS); break; default: define('BIND_MODULE', 'index'); define('CONF_PATH', APP_PATH . 'config' . DS); } -
CONF_PATH必须在Container::get('app')->run()前定义,否则框架仍从默认APP_PATH/config/加载 - 每个子目录(如
app/admin/config/)下需存在完整的配置文件,至少包含database.php、app.php,否则会 fallback 到根配置
config/app.php 中禁止写死 default_module
若在 config/app.php 中设了 'default_module' => 'index',它会覆盖 BIND_MODULE,导致域名判断失效。
- 必须把
'default_module' => BIND_MODULE(注意不是字符串'index') - 同时确保
'url_domain_deploy' => true已开启,否则Route::domain()不生效 - 不要在
route.php里用Route::domain('admin.example.com', 'admin')试图“绑定模块”——这仅影响 URL 解析路径,不改变配置加载路径
数据库等扩展配置需按目录隔离
TP5 的 database.php 是单例加载,不会因模块切换自动重载。如果不同域名需要不同数据库连接,不能只改配置名,必须让框架重新读取。
- 在
CONF_PATH对应目录下放独立的database.php,内容与根目录一致但连接参数不同 - 避免使用
Db::connect(['database' => 'xxx'])手动指定,这绕过配置体系,易漏改模型中的protected $connection - 模板、语言包同理:把
lang/、view/目录也按模块拆到app/admin/下,再通过view_path配置指向对应路径
真正容易被忽略的是:TP5 没有“应用级”概念,所谓“不同域名加载不同配置”,本质是靠 CONF_PATH + BIND_MODULE 两个宏强行模拟。一旦漏定义 CONF_PATH,或在 app.php 里写死模块名,整个分流就静默退化为默认配置——连错误提示都不会出现。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











