每个应用必须有独立的 route/app.php;域名绑定 Route::domain() 只能写在项目级 route/app.php 或 app/common/route.php 中,不可放在子应用路由内;Nginx 伪静态规则须保留 HTTP_HOST 且运行目录设为 /public;注解路由需手动扩展扫描路径并清空 runtime/annotation 缓存。

每个应用必须有独立的 route/app.php
ThinkPHP 多应用模式下,路由不是集中写在根目录 route/app.php,而是按应用拆分:每个子应用(如 app/admin/)需自带 route/app.php,且该文件只对本应用生效。框架启动时会根据当前应用名自动加载对应路径下的路由文件。
常见错误是只改了根目录的 route/app.php,结果 admin 域名访问时仍走 index 应用的路由;或误删某个子应用的 route/app.php,导致报错 App not exists。
-
app/index/route/app.php控制前台首页、用户注册等路由 -
app/admin/route/app.php专管后台登录、菜单、系统设置等 - 文件可以为空,但必须存在;若缺失,框架无法完成应用初始化
- 不建议在子应用路由中使用
Route::domain()—— 域名绑定应在主路由(route/app.php或app/common/route.php)统一配置
Route::domain() 必须写在全局路由入口,不能放子应用里
子域名绑定(如 admin.example.com → app/admin)属于“请求进入前”的上下文识别,必须在框架加载应用前就完成。因此 Route::domain() 只能出现在项目级路由文件中,典型位置是 route/app.php 或 app/common/route.php。
如果把它写进 app/admin/route/app.php,运行时根本不会执行——因为此时应用已经确定为 admin,再绑定已无意义。
立即学习“PHP免费学习笔记(深入)”;
- 正确写法示例:
Route::domain('admin', 'admin');(放在route/app.php) - 支持通配:
Route::domain('*', 'index');捕获未显式声明的域名 - TP6/8 已废弃
APP_SUB_DOMAIN_DEPLOY配置项,别在config/app.php里设它 - 二级域名必须配合 Nginx 独立
server块或正确伪静态规则,否则HTTP_HOST可能拿不到真实值
伪静态规则没配对,route/app.php 再规范也进不去
很多开发者把 Route::domain() 配好了,但访问 admin.example.com 依然进 index 应用——根本原因是 Nginx 没把请求真正交给框架,而是直接返回 404 或兜底到 /index.php?s=xxx,导致框架无法解析域名上下文。
宝塔默认的 ThinkPHP 伪静态规则只适配单应用,会把所有请求重写成 /index.php?s=$1,丢失原始 Host 信息,Route::domain() 完全失效。
- 必须删除宝塔面板中已有的 ThinkPHP 伪静态规则
- 改用多应用专用规则(关键点:不破坏
$_SERVER['HTTP_HOST']):if(!-e $request_filename) { rewrite ^/([a-z0-9A-Z_-]+)/(.*)$ /index.php?s=$1/$2 last; rewrite ^/(.*)$ /index.php?s=$1 last; } -
last不可换成break,否则 PHP-FPM 不会重新匹配 location,PATH_INFO 为空,路由解析失败 - 确保网站「运行目录」设为
/public(宝塔下拉选择,非手动输入)
注解路由(#[Route])要手动扩展扫描路径
ThinkPHP 8 启用注解路由后,#[Route] 默认只扫描 appcontroller,而多应用下 admin 的控制器在 appdmincontroller,自然被忽略——这不是 bug,是扫描范围没更新。
需要显式告诉 think-annotation 扩展去哪找类:
- 编辑
config/annotation.php,修改'scan' => ['appcontroller']为:['appcontroller', 'appdmincontroller', 'apppicontroller'] - 或更灵活的方式:用通配
'app\*\controller'(注意双反斜杠转义) - 每次增删应用后,记得清空
runtime/annotation目录,否则旧缓存会导致注解不生效 - 验证是否生效:命令行运行
php think route:list,检查输出中是否包含 admin 下的注解路由
route/app.php 的位置关系——前者决定请求能不能进框架,后者决定进框架后走哪条路。两者缺一不可,且顺序不能颠倒。



















