如何在单个 Laravel 应用中统一管理多个子域名路由

1次阅读

如何在单个 Laravel 应用中统一管理多个子域名路由

无需为每个子域名部署独立 laravel 应用;laravel 原生支持基于域名的路由分组,可在一个项目中高效、清晰地分离 `shop.mycompany.com` 和 `comment.mycompany.com` 等不同子域的逻辑。

Laravel 提供了强大的 Route::domain() 方法,允许你按请求主机名(Host header)精准匹配并分发路由,从而实现在同一套代码、同一个应用实例中支撑多个功能独立的子域名站点。这不仅降低运维复杂度(无需重复部署、配置 nginx/apache 虚拟主机指向不同目录),还能共享数据库、缓存、认证、队列等核心服务,显著提升开发与维护效率。

✅ 正确做法:使用域名路由分组

在 routes/web.php 中,按子域组织路由逻辑:

// 处理 shop.mycompany.com 及其子域(如 us.shop.mycompany.com) Route::domain('{shop}.mycompany.com')->group(function () {     Route::get('/item', function () {         return view('shop.item');     })->name('shop.item');      // 其他购物相关路由... });  // 专用于 comment.mycompany.com Route::domain('comment.mycompany.com')->group(function () {     Route::get('/customer', function () {         $id = request('id');         return view('comment.form', compact('id'));     })->name('comment.form');      Route::post('/submit', [CommentController::class, 'store'])          ->name('comment.store'); });

? 注意:{shop} 是通配符参数,可用于动态识别子域(如 us.shop.mycompany.com → $shop = ‘us.shop’),需配合 Route::middleware(‘set-subdomain’) 或在控制器中通过 request()->route(‘shop’) 获取。

⚠️ 关键前提与配置

  • dns 与 Web 服务器必须正确解析所有子域:确保 shop.mycompany.com、comment.mycompany.com 均解析到同一服务器 IP,并在 Nginx/Apache 中配置泛解析或显式 server block,将请求统一指向 Laravel 的 public/ 目录(无需为每个子域设置独立根目录)。
  • 禁用 app_URL 对路由生成的干扰:Laravel 默认根据 APP_URL 生成 URL,多子域场景下建议在 config/app.php 中移除 APP_URL,改用运行时动态判断:
    // 在 AppServiceProvider@register() 中 URL::forceRootUrl(Request::getSchemeAndHttpHost());
  • 中间件增强控制(可选):可自定义中间件验证子域白名单、自动注入租户上下文或切换数据库连接,例如:
    class EnsureValidSubdomain {     public function handle($request, Closure $next)     {         $host = $request->getHost();         if (!in_array($host, ['shop.mycompany.com', 'comment.mycompany.com'])) {             abort(404);         }         return $next($request);     } }

✅ 总结

你完全不需要为 comment.mycompany.com 新建一个 Laravel 项目——只需利用 Route::domain() 进行逻辑隔离,搭配合理的服务器配置与少量适配代码,即可安全、灵活、可扩展地支撑多子域业务。这种方式更符合 Laravel 的设计哲学:约定优于配置,集中优于分散。

text=ZqhQzanResources