thinkphp 5.1靠app_sub_domain_deploy配置自动识别二级域名但已废弃;6.x需同时开启url_domain_deploy并用route::domain()显式绑定;8.0则完全依赖#[domain]注解+annotation.php扫描白名单,且必须php≥8.0.2并清缓存。

ThinkPHP 不同版本对二级域名的支持逻辑差异很大,不是改几个配置就能通用的事。5.1 是靠传统配置驱动,6.x 开始转向路由声明式绑定,8.0 则完全依赖 PHP 8 原生特性与显式扫描机制——版本一换,整套配置就得重来。
ThinkPHP 5.1:靠配置自动识别,但已废弃且不安全
TP5.1 使用 APP_SUB_DOMAIN_DEPLOY 和 MODULE_ALLOW_LIST 实现子域名映射,例如在 config/app.php 中设置:
'app_sub_domain_deploy' => true'module_allow_list' => ['admin', 'api']-
'url_domain_deploy' => false(该选项在 5.1 中无效)
框架会自动将 admin.tp5.test 解析到 app/admin/ 模块。但注意:该机制已被官方明确废弃,5.1 已停止维护,存在远程代码执行等高危漏洞,2025 年起不应再用于新项目或生产环境。
ThinkPHP 6.x:路由层绑定 + 框架开关双生效
TP6.x 彻底移除自动子域名识别,改为在路由文件中显式声明。必须同时满足两个条件才能生效:
- 在
config/app.php中开启:'url_domain_deploy' => true(APP_SUB_DOMAIN_DEPLOY已无效) - 在
route/app.php或app/common/route.php中注册绑定:Route::domain('admin', 'admin');
此时访问 admin.tp6.test 才会加载 app/admin/ 应用。若只开配置不开路由,或只写路由不开启开关,都会返回 404。另外,TP6 要求 Web 服务器的 DocumentRoot 必须指向 public/ 目录,且 AllowOverride All 必须启用,否则伪静态规则不触发。
ThinkPHP 8.0:注解驱动 + 扫描白名单强制指定
TP8.0 不再支持 Route::domain() 这类函数式写法,全部改为 PHP 原生 Attribute 注解,并且多模块控制器不会被自动扫描。关键步骤有三:
- 确保
config/annotation.php中的scan列表包含你的模块命名空间,例如:'app\admin\controller'、'app\api\controller' - 在对应控制器类或方法上添加
#[Domain('admin')]注解(需先安装topthink/think-annotation) - 每次修改后必须运行
php think clear --all清空所有缓存,否则注解不生效
若漏掉扫描路径配置,哪怕注解写得再规范,框架也完全“看不见”该模块——这是 TP8.0 多模块二级域名最常见的 404 原因。同时,PHP 版本必须 ≥8.0.2,否则连语法解析都失败。
共性前提:系统与服务器配置不能少
无论哪个版本,以下三步缺一不可:
-
hosts 文件:在
/etc/hosts(macOS/Linux)或C:\Windows\System32\drivers\etc\hosts(Windows)中添加如127.0.0.1 admin.tp6.test,保存为 UTF-8 无 BOM,并执行ipconfig /flushdns或sudo dscacheutil -flushcache -
Web 服务器虚拟主机:Apache/Nginx 必须为每个二级域名单独配置
ServerName或server_name,且DocumentRoot或root指向项目public/目录 -
URL 重写支持:Apache 需启用
mod_rewrite并在目录配置中设AllowOverride All;Nginx 的location /块中需含正确的try_files $uri $uri/ /index.php?$query_string;规则
光配框架不配服务器,或只改 hosts 不动 vhost,结果都是打不开页面。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











