Laravel 12原生不直接支持多级子域名自动路由分组,需通过解析Host头、动态绑定域参数并配合Route::domain()通配分组或全局中间件实现租户识别与上下文挂载。

Laravel 12 原生不直接支持按多级子域名(如 zzz.tenant.example.com)自动分组路由,但可通过请求对象的 host 信息手动提取并匹配,核心在于**解析 Host 头、动态绑定域参数、配合路由分组与中间件控制**。
从请求中提取多级子域名
在路由定义或中间件中,用 $request->getHost() 获取完整域名,再用 PHP 字符串或正则拆解:
-
parse_url($request->getHost(), PHP_URL_HOST)确保获取纯 host - 用
explode('.', $host)得到数组['zzz', 'tenant', 'example', 'com'] - 取前两级:
$sub1 = $parts[0] ?? null; $sub2 = $parts[1] ?? null;(注意顺序和长度校验) - 更健壮写法推荐正则:
preg_match('/^([a-z0-9\-]+)\.([a-z0-9\-]+)\.example\.com$/i', $host, $matches),匹配成功后$matches[1]是 zzz,$matches[2]是 tenant
在 RouteServiceProvider 中动态注册带域约束的路由
修改 app/Providers/RouteServiceProvider.php 的 boot() 方法,用 Route::domain() 绑定变量:
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 写一个通配 domain 模式:
Route::domain('{sub1}.{sub2}.example.com')->group(...) - 在 group 内部,所有路由自动接收
$sub1和$sub2作为参数 - 可加 where 约束避免误匹配:
->where(['sub1' => '[a-z0-9\-]+', 'sub2' => '[a-z0-9\-]+']) - 注意:Laravel 12 要求 domain 字符串必须是静态或含明确占位符,不能传动态计算的字符串
用中间件统一解析并挂载租户上下文
比 domain 分组更灵活的方式是全局中间件,在请求生命周期早期识别租户并存入 request 或服务容器:
- 创建中间件
ResolveTenantFromSubdomains - 在中间件里解析
zzz.tenant,查数据库或配置确认租户有效性 - 调用
$request->attributes->set('tenant_code', $sub1); $request->attributes->set('tenant_type', $sub2); - 后续控制器或模型可直接通过
$request->tenant_code访问 - 配合
middleware('tenant')应用于需要隔离的路由组
注意事项与常见陷阱
本地开发需配合 hosts 文件或工具(如 Laravel Valet / Dnsmasq)支持泛解析;生产环境 Nginx/Apache 必须将 *.*.example.com 的请求正确转发给 Laravel(不能只配 *.example.com);HTTPS 证书需覆盖多级通配(如 *.*.example.com 不被主流 CA 支持,实际常用 *.example.com + 后端逻辑区分)。


















