Symfony 路由支持 host 選項,根據 HTTP Host 頭匹配不同路由,實現多域名/子域名應用架構。
mobile_homepage:
path: /
host: m.example.com
defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }
homepage:
path: /
defaults: { _controller: AcmeDemoBundle:Main:homepage }
AcmeDemoBundle:Main:mobileHomepage AcmeDemoBundle:Main:homepage
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('mobile_homepage', new Route('/', [
'_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
], [], [], 'm.example.com'));
$collection->add('homepage', new Route('/', [
'_controller' => 'AcmeDemoBundle:Main:homepage',
]));
return $collection;
效果:同路徑 /,Host 為 m.example.com 命中移動端控制器,其他域名命中默認控制器。
projects_homepage:
path: /
host: "{project_name}.example.com"
defaults: { _controller: AcmeDemoBundle:Main:projectHomepage }
訪問 foo.example.com/ → $project_name = 'foo' 传給控制器。
mobile_homepage:
path: /
host: "{subdomain}.example.com"
defaults:
_controller: AcmeDemoBundle:Main:mobileHomepage
subdomain: m
requirements:
subdomain: m|mobile
僅匹配 m.example.com 和 mobile.example.com,默認 m。
mobile_homepage:
path: /
host: "m.{domain}"
defaults:
_controller: AcmeDemoBundle:Main:mobileHomepage
domain: '%domain%'
requirements:
domain: '%domain%'
%domain% 從 parameters.yml 讀取,避免硬編碼域名。
acme_hello:
resource: '@AcmeHelloBundle/Resources/config/routing.yml'
host: "hello.example.com"
導入的所有路由自動獲得 hello.example.com 前綴。
$crawler = $client->request(
'GET',
'/homepage',
[],
[],
['HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain')]
);
Functional 測試必須設置 HTTP_HOST 服務器參數,否則路由不匹配。
%domain% 參數,區分 dev/stage/prod 環境requirements 限制佔位符範圍,防止路由劫持defaults,否則生成 URL 時需強制傳值| 問題 | 原因 | 解決 |
|---|---|---|
| 生成 URL 缺少 Host | 佔位符無默認值 | 添加 defaults 或調用時傳參 |
| 子域名路由不匹配 | Nginx/Apache 未轉發 Host 頭 | 配置 proxy_set_header Host $host; |
| 測試 404 | 未設置 HTTP_HOST | 請求參數添加 HTTP_HOST |
Symfony2 域名路由功能強大,支持靜態域名、動態佔位符、正則約束、參數化配置、批量導入。合理使用可構建清晰的多域名應用架構(主站、移動端、API、租戶隔離等)。核心在於:Host 匹配優先於 Path,佔位符需約束與默認值雙重保障。