thinkphp5 域名绑定模块需开启 url_domain_deploy => true 并在 route/app.php 中用 route::domain() 定义规则;nginx 仅需透传 http_host,确保 fastcgi_param script_filename 和 include fastcgi_params 存在。

ThinkPHP5 在 LNMP 环境下实现域名绑定模块,关键不在 Nginx 配置,而在于框架路由层的 Route::domain() 声明 + url_domain_deploy 开启。Nginx 只需正确透传 HTTP_HOST,其余全由 TP5 路由引擎完成匹配。
必须开启域名部署开关
TP5 不会自动识别 Host 头做路由分发,必须显式启用。在 config/app.php 中确认存在且为 true:
'url_domain_deploy' => true,
注意:APP_SUB_DOMAIN_DEPLOY 是 TP3/TP4 的旧配置,TP5 已废弃,写进去也无效。该配置只影响路由解析阶段,不影响静态资源或 URL 生成逻辑。
域名规则必须写在 route/app.php 里
Route::domain() 只有在 route/app.php(不是 route/route.php 或 app/route.php)中定义才生效。常见错误包括:
- 把规则写进
config/route.php—— 框架不读 - 在控制器里调用
Route::domain()—— 执行时机太晚,路由已初始化完毕 - 误用
bind()方法试图“绑定模块” —— 这是入口级行为,和域名路由冲突
正确写法示例(route/app.php):
use think\Route;<br>Route::domain('admin.example.com', function () {<br> Route::get('/', 'admin/index/index');<br> Route::get('user/:id', 'admin/user/read');<br>});<br>Route::domain('api.example.com', ['api/v1.user@get', 'api/v1.order@post']);
第二参数支持闭包或数组,但不能是字符串路径(如 'admin/index' 会直接报错 Invalid route rule)。
LNMP 配置只需保证 Host 头可达
Nginx 不需要为每个域名写独立 server 块,只要确保请求的 Host 头能被 PHP 正确读取即可。最简配置如下:
server {<br> listen 80;<br> server_name example.com www.example.com admin.example.com api.example.com;<br> root /home/wwwroot/example.com/public;<br> index index.php;<br><br> location / {<br> if (!-e $request_filename) {<br> rewrite ^(.*)$ /index.php?s=$1 last;<br> }<br> }<br><br> location ~ \.php$ {<br> fastcgi_pass 127.0.0.1:9000;<br> fastcgi_index index.php;<br> fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;<br> include fastcgi_params;<br> }<br>}
重点检查:fastcgi_param 必须包含 SCRIPT_FILENAME,且 include fastcgi_params 不可遗漏 —— 否则 $_SERVER['HTTP_HOST'] 为空,域名匹配必然失败。
本地开发时 Host 匹配要带端口
本地用 php -S 或 XAMPP/Nginx 访问 localhost:8080 时,$_SERVER['HTTP_HOST'] 是 localhost:8080,而你写的 Route::domain('admin.example.com', ...) 完全不匹配。
调试建议:
- 临时加一条开发专用规则:
Route::domain('localhost:8080', [...]) - 或统一用 hosts 绑定真实域名(如
127.0.0.1 admin.example.com),再配 Nginx server_name - 切勿依赖浏览器地址栏显示的域名 —— 以
var_dump($_SERVER['HTTP_HOST'])输出为准
泛域名规则(如 Route::domain('*', ...))必须放在所有精确匹配之后,否则会拦截掉 admin.example.com 等具体域名。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











