ThinkPHP多域名部署需按域名隔离配置、路由、中间件和模板缓存:拆分domain配置文件按需加载;用Route::domain()和域名感知中间件实现懒加载;为各域名设置独立路由缓存路径与view_path;统一模板后缀并分离cache_path。

ThinkPHP 多域名下 config/app.php 的加载时机很关键
默认情况下,ThinkPHP 在每次请求启动时都会完整加载并解析 config/app.php,哪怕你只用其中几个配置项。多域名部署时,如果每个域名都走同一套配置逻辑,又没做隔离,就会反复加载冗余配置、触发重复判断,拖慢响应。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 把域名相关配置(如
app_name、default_lang、template路径)从app.php拆到独立文件,比如config/domain/{domain}.php - 在
app/common.php或app/provider.php中,用$_SERVER['HTTP_HOST']提前识别域名,再按需Config::load()对应配置,避免全量加载 - 注意:不要在
config/app.php里写动态逻辑(比如if (strpos($_SERVER['HTTP_HOST'], 'xxx')) {...}),这会导致 opcache 失效、配置无法被缓存
路由和中间件的域名级懒加载必须手动控制
ThinkPHP 默认会预加载全部路由规则和中间件类,但多域名场景下,A 域名根本用不到 B 域名的路由或权限中间件,却仍被加载进内存——既占资源,又延长了 autoload 查找链。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用
Route::domain()显式声明域名路由分组,而不是靠Route::rule()+ 条件判断 - 中间件注册改用闭包方式,在中间件类内部检查
Request::domain(),不匹配直接return $next($request)短路,避免后续初始化 - 禁用全局中间件(
app/middleware.php)中与域名强相关的逻辑;改放到对应app/middleware/DomainXxxMiddleware.php并仅在对应域名路由中调用
think:route:clear 缓存失效是多域名部署最常踩的坑
执行 think:route:clear 会清空所有域名的路由缓存,但如果你没配置好 route_config_file 或用了动态域名匹配,下次请求时会重新扫描全部控制器和注解,导致首屏明显变慢——尤其在生产环境自动部署后容易被忽略。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 确保每个域名有独立的路由缓存文件路径,例如在
config/route.php中设置:'config_file' => RUNTIME_PATH . 'route_' . str_replace('.', '_', $_SERVER['HTTP_HOST']) . '.php' - 部署脚本中,不要无差别执行
php think route:clear,而是按域名逐个清理:HTTP_HOST=shop.example.com php think route:clear - 检查
route/目录权限,避免因写入失败导致缓存降级为运行时实时解析
模板引擎的 view_path 和域名绑定必须物理隔离
多个域名共用一套 view/ 目录,靠 think\template\driver\File::parseTemplate 动态拼路径,会导致模板缓存 key 冲突、opcache 频繁失效,甚至 A 域名误渲染了 B 域名的模板文件。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 为每个域名建独立视图目录,如
view/shop/、view/api/,并在域名配置中显式指定:'view_path' => APP_PATH . 'view/' . $domain_prefix . '/' - 禁用
template.view_suffix的动态修改,统一用.html;避免因后缀不同导致同一模板被多次编译 - 开启
template.cache_path分离,比如设为runtime/view_cache/{domain}/,防止编译产物互相覆盖
域名越多,配置文件和缓存路径的命名一致性越重要;漏掉一个下划线或大小写差异,就可能让两个域名共享同一份缓存,问题很难复现。


















