Php Symfony 2如何通过访问请求对象动态添加路由
背景: 我正在尝试根据请求主机有条件地加载路由。我有一个数据库设置,其中有映射到模板的主机。如果用户来自主机Php Symfony 2如何通过访问请求对象动态添加路由,php,symfony,event-listener,symfony-2.5,Php,Symfony,Event Listener,Symfony 2.5,背景: 我正在尝试根据请求主机有条件地加载路由。我有一个数据库设置,其中有映射到模板的主机。如果用户来自主机a,并且使用了模板TA,我想加载该模板的路由。如果它们来自主机B,则加载该模板的路由(TB) 我必须这样做的原因是,每个模板将共享许多路由。但是,对于给定模板,存在一些独特的路由 将每个模板路由限制到给定的主机是可以的,但实际上有1000个主机 我尝试过的: 我已经尝试了一个自定义路由加载器,如以下文档所述: 但是,当我配置服务并尝试注入“@request”时,构造函数失败,因为$req
a
,并且使用了模板TA
,我想加载该模板的路由。如果它们来自主机B
,则加载该模板的路由(TB
)
我必须这样做的原因是,每个模板将共享许多路由。但是,对于给定模板,存在一些独特的路由
将每个模板路由限制到给定的主机是可以的,但实际上有1000个主机
我尝试过的:
我已经尝试了一个自定义路由加载器,如以下文档所述:
但是,当我配置服务并尝试注入“@request”
时,构造函数失败,因为$request为null
services:
acme_demo.routing_loader:
class: Acme\DemoBundle\Routing\ExtraLoader
arguments: ["@request"]
tags:
- { name: routing.loader }
类别:
<?php
namespace: Acme\DemoBundle\Routing;
use Symfony\Component\HttpFoundation\Request;
class ExtraLoader
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
// ...
}
我最接近实现这一目标的方法是遵循以下指南:
我在这方面遇到的问题是,我试图在控制器上使用
注释
,但我似乎无法使Symfony\Component\Routing\Loader\AnnotationFileLoader
正常工作。好的,我终于找到了一个可行的解决方案,它是上述几种指南的混合
Im使用内核请求侦听器:
services:
website_listener:
class: NameSpace\Bundle\EventListener\WebsiteListener
arguments:
- "@website_service"
- "@template_service"
- "@sensio_framework_extra.routing.loader.annot_dir"
- "@router"
- "%admin_domain%"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 33 }
听众:
<?php
namespace NameSpace\WebsiteBundle\EventListener;
use NameSpace\TemplateBundle\Service\TemplateService;
use NameSpace\WebsiteBundle\Service\WebsiteService;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\PropertyAccess\PropertyAccess;
class WebsiteListener
{
/**
* @var WebsiteService
*/
protected $websiteService;
/**
* @var TemplateService
*/
protected $templateService;
/**
* @var AnnotationDirectoryLoader
*/
protected $loader;
/**
* @var Router
*/
protected $router;
/**
* @var string
*/
protected $adminDomain;
public function __construct(WebsiteService $websiteService, TemplateService $templateService, AnnotationDirectoryLoader $loader, Router $router, $adminDomain)
{
$this->websiteService = $websiteService;
$this->templateService = $templateService;
$this->loader = $loader;
$this->router = $router;
$this->adminDomain = $adminDomain;
}
public function loadRoutes()
{
$template = $this->templateService->getTemplateByAlias($this->websiteService->getWebsite()->getTemplate());
$routes = $this->loader->load($template['routes'],'annotation');
$allRoutes = $this->router->getRouteCollection();
$allRoutes->addCollection($routes);
}
public function onKernelRequest(GetResponseEvent $event)
{
try {
$this->websiteService->handleRequest($event->getRequest());
$this->loadRoutes();
} catch(NotFoundHttpException $e) {
if($event->getRequest()->getHost() !== $this->adminDomain){
throw $e;
}
}
}
}
<?php
namespace NameSpace\WebsiteBundle\EventListener;
use NameSpace\TemplateBundle\Service\TemplateService;
use NameSpace\WebsiteBundle\Service\WebsiteService;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\PropertyAccess\PropertyAccess;
class WebsiteListener
{
/**
* @var WebsiteService
*/
protected $websiteService;
/**
* @var TemplateService
*/
protected $templateService;
/**
* @var AnnotationDirectoryLoader
*/
protected $loader;
/**
* @var Router
*/
protected $router;
/**
* @var string
*/
protected $adminDomain;
public function __construct(WebsiteService $websiteService, TemplateService $templateService, AnnotationDirectoryLoader $loader, Router $router, $adminDomain)
{
$this->websiteService = $websiteService;
$this->templateService = $templateService;
$this->loader = $loader;
$this->router = $router;
$this->adminDomain = $adminDomain;
}
public function loadRoutes()
{
$template = $this->templateService->getTemplateByAlias($this->websiteService->getWebsite()->getTemplate());
$routes = $this->loader->load($template['routes'],'annotation');
$allRoutes = $this->router->getRouteCollection();
$allRoutes->addCollection($routes);
}
public function onKernelRequest(GetResponseEvent $event)
{
try {
$this->websiteService->handleRequest($event->getRequest());
$this->loadRoutes();
} catch(NotFoundHttpException $e) {
if($event->getRequest()->getHost() !== $this->adminDomain){
throw $e;
}
}
}
}