ThinkPHP需Web服务器与框架协同实现多域名支持:Web层配置域名指向public目录并启用重写,框架层开启url_domain_deploy并配置domain_bind或Route::domain()实现应用隔离或子域名路由。

ThinkPHP 本身不自动区分域名,所有域名默认都走同一个应用入口。要让不同域名访问不同模块或应用,必须在 Web 服务器层和框架层协同配置——缺一不可。核心是:DNS 解析 → Web 服务器分发 → 框架识别并路由。
一、Web 服务器配置(基础前提)
这是第一步,也是最容易出错的环节。所有域名必须正确指向项目的 public/ 目录,且启用 URL 重写功能。
-
Apache:每个域名需单独配置
<VirtualHost>,DocumentRoot必须设为项目public/目录;启用mod_rewrite,并在配置中加入AllowOverride All,否则.htaccess不生效 -
Nginx:每个域名对应一个
server块,root指向public/;location ~ \.php$中必须包含:fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
否则会出现 “No input file specified” 错误 - 本地开发时,还需修改系统
hosts文件(如 Windows 的C:\Windows\System32\drivers\etc\hosts),添加类似:127.0.0.1 admin.example.com127.0.0.1 api.example.com
并执行ipconfig /flushdns(Windows)或sudo dscacheutil -flushcache(macOS)刷新缓存
二、框架层启用域名识别
仅靠服务器配置还不够,ThinkPHP 必须知道“当前请求来自哪个域名”,才能做后续路由或应用切换。关键配置项只有一个:
在 config/app.php 中设置:'url_domain_deploy' => true,
立即学习“PHP免费学习笔记(深入)”;
这个开关告诉框架:解析 URL 时要读取 Host 头,参与路由判断。注意:
• APP_SUB_DOMAIN_DEPLOY 是 TP5 及更早版本的配置,TP6+ 已废弃;
• 不开启此项,Route::domain() 和 domain_bind 都不会生效。
三、按域名绑定不同应用(推荐用于生产隔离)
适用于多个完全独立的应用(如后台 admin、API 接口、移动端 m),每个应用有自己独立的控制器、配置、中间件。
- 在
config/app.php中配置domain_bind数组:'domain_bind' => ['admin.example.com' => 'admin','api.example.com' => 'api','m.example.com' => 'mobile','*' => 'index'], - 确保对应目录真实存在,例如
app/admin/controller/Index.php,且命名空间为app\admin\controller - 绑定后,框架会自动切换视图路径(
app/admin/view/)、配置加载顺序(优先读app/admin/config/)、中间件和事件监听器
四、按子域名动态路由(适合单应用内功能划分)
适用于同一套代码下,用子域名区分功能区域(如 user.example.com 和 pay.example.com 都属于主应用,只是路由前缀不同)。
- 在
route/app.php中使用Route::domain():use think\facade\Route;Route::domain('user', 'user');Route::domain('pay', 'pay');Route::domain('*', 'index'); - 这种写法只影响路由匹配,不切换应用上下文,控制器仍从
app/controller/下加载(除非配合命名空间前缀规则) - 适合轻量级分流,不适合数据库、缓存、模板路径完全隔离的场景



















