具有动态默认子域的Symfony匹配路由

时间:2014-08-10 20:02:29

标签: symfony

我知道可以在多个子域上匹配路由,如下所示:

irc_backend.report.stacking_issue:
    path: /reports/stacking-issues
    host: {subdomain}.domain.com
    defaults:  
        _controller: IRCBackendBundle:Reports/Product/StackingIssueReport:index
        subdomain: backend
    requirements:
        subdomain: backend|dev.backend

这有效,但这种方法的问题是每次使用路由器生成URL时,我都必须指定要使用的子域。我希望每次从路由器获取URL时都不必传入当前子域,而是默认使用与当前请求相同的子域。我需要一种动态设置默认子域值的方法:

irc_backend.report.stacking_issue:
    path: /reports/stacking-issues
    host: {subdomain}.domain.com
    defaults:  
        _controller: IRCBackendBundle:Reports/Product/StackingIssueReport:index
        subdomain: %subdomain%
    requirements:
        subdomain: backend|dev.backend

我尝试使用事件监听器来设置容器参数,但是当调用监听器时,容器已经被编译,因此你得到一个"不可能在冻结的ParameterBag上调用set()。 #34;如果你试图在那里设置容器参数。

1 个答案:

答案 0 :(得分:1)

不幸的是,仅Symfony还没有内置功能来回收当前路由中丢失的路由参数 - 我相信至少对于主机而言,需要解决的问题是 SaaS 解决方案的数量不断增加驻留路线参数。我通过简单地扩展 Symfony \ Bridge \ Twig \ Extension \ RoutingExtension 解决了完全相同的问题,如果没有为视图助手提供域参数,则提供当前相应的路由参数。

我在AppBundle \ Extension \ Twig中创建了一个DomainAwareRoutingExtension类,如下所示

<?php

namespace AppBundle\Extension\Twig;

use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class DomainAwareRoutingExtension extends RoutingExtension
{

    /** @var \Symfony\Component\HttpFoundation\Request */
    private $request;

    /**
     * DomainAwareRoutingExtension constructor.
     *
     * @param UrlGeneratorInterface  $generator
     * @param null|RequestStack      $requestStack
     */
    public function __construct(UrlGeneratorInterface $generator, RequestStack $requestStack = null)
    {
        parent::__construct($generator);

        $this->request = ($requestStack) ? $requestStack->getCurrentRequest() : null;
    }

    public function getPath($name, $parameters = [], $relative = false)
    {
        if (empty($parameters['domain']) && !empty($this->request) && !empty($this->request->attributes->get('domain'))) {
            $parameters['domain'] = $this->request->attributes->get('domain');
        }
        return parent::getPath($name, $parameters, $relative);
    }

}

并将其注册为服务

#services.yml
parameters:
twig.extension.routing.class: AppBundle\Extension\Twig\DomainAwareRoutingExtension

services:
    twig.extension.routing:
        class: '%twig.extension.routing.class%'
        public: false
        arguments:
            - '@router'
            - '@request_stack'

在您的情况下,您应该使用“子域名”替换代码中的“域名”。对于Symfony2 Twig overriding default path function来说,获得灵感的归功于@Cerad和@Gambit。