Symfony - 在 onKernelRequest 中使用 twig 终止会话
Symfony - using twig in onKernelRequest kills session
我在 symfony 4.3 中遇到一个奇怪的问题(也在 4.2 中测试过 - 相同的行为) - 我正在使用 EventListener 来处理请求 - 代码如下:
<?php
namespace App\EventListener;
use App\Entity\Company;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
class ShopListener implements EventSubscriberInterface
{
/** @var EntityManagerInterface */
protected $em;
/** @var Environment */
protected $twig;
public function __construct(EntityManagerInterface $entityManager, Environment $twig)
{
$this->em=$entityManager;
$this->twig=$twig;
}
public function onKernelRequest(RequestEvent $event)
{
if($event->isMasterRequest()===false) {
return;
}
/** @var Request $request */
$request=$event->getRequest();
$subDomain=$request->attributes->get('domain');
if($subDomain===null) {
return;
}
$company=$this->em->getRepository(Company::class)->findOneBy([
'subDomain' => $subDomain,
]);
if($company instanceof Company && $company->shopIsOnline()) {
$request->attributes->set('company',$company);
return;
}
$event->setResponse(
new Response($this->twig->render('page/shop_not_found.html.twig'),404)
);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest',0],
];
}
}
注册该侦听器后,$request->getSession()
在我的控制器中始终是 null
(工具栏也注意到,没有注册会话)。注销时,会话在那里,但监听器中的逻辑被跳过。我尝试过优先考虑以确保没有其他听众干扰。
看起来,已经注册该事件会终止会话(即使 onKernelRequest 为空),这很难相信。
我错过了什么?
会话由 Symfony\Component\FrameworkBundle\EventListener\SessionListener
侦听器在 kernel.request
事件上创建(优先级为 128)。
此事件具有特定行为:如果侦听器设置响应,"the process skips directly to the kernel.response event" 引用 the documentation。我怀疑它可能会导致问题。
尝试将您的监听器的优先级设置为 < 0(我让您尝试了很多次),并请检查探查器 "Events" 部分 (/_profiler/latest?panel=events
).
的顺序
找到解决方案 - 问题是在构造函数中注入 twig-environment - 没有树枝一切都按预期工作。我想,在此阶段加载 twig-environment 会对会话产生影响(比如过早加载)。
我将侦听器移至 onKernelController 并对其进行了修改:
<?php
namespace App\EventListener;
use App\Entity\Company;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
class ShopListener implements EventSubscriberInterface
{
/** @var EntityManagerInterface */
protected $em;
/** @var Environment */
protected $twig;
public function __construct(EntityManagerInterface $entityManager, Environment $twig)
{
$this->em=$entityManager;
$this->twig=$twig;
}
public function onKernelController(ControllerEvent $controllerEvent)
{
if($controllerEvent->isMasterRequest()===false) {
return;
}
/** @var Request $request */
$request=$controllerEvent->getRequest();
$subDomain = $request->attributes->get('domain');
if($subDomain===null) {
return;
}
$company=$this->em->getRepository(Company::class)->findOneBy([
'subDomain' => $subDomain,
]);
if($company instanceof Company && $company->shopIsOnline()) {
$request->attributes->set('company',$company);
return;
}
$controllerEvent->setController(
function() {
return new Response($this->twig->render('page/shop_not_found.html.twig'),404);
}
);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => ['onKernelController',128],
];
}
}
我在 symfony 4.3 中遇到一个奇怪的问题(也在 4.2 中测试过 - 相同的行为) - 我正在使用 EventListener 来处理请求 - 代码如下:
<?php
namespace App\EventListener;
use App\Entity\Company;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
class ShopListener implements EventSubscriberInterface
{
/** @var EntityManagerInterface */
protected $em;
/** @var Environment */
protected $twig;
public function __construct(EntityManagerInterface $entityManager, Environment $twig)
{
$this->em=$entityManager;
$this->twig=$twig;
}
public function onKernelRequest(RequestEvent $event)
{
if($event->isMasterRequest()===false) {
return;
}
/** @var Request $request */
$request=$event->getRequest();
$subDomain=$request->attributes->get('domain');
if($subDomain===null) {
return;
}
$company=$this->em->getRepository(Company::class)->findOneBy([
'subDomain' => $subDomain,
]);
if($company instanceof Company && $company->shopIsOnline()) {
$request->attributes->set('company',$company);
return;
}
$event->setResponse(
new Response($this->twig->render('page/shop_not_found.html.twig'),404)
);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest',0],
];
}
}
注册该侦听器后,$request->getSession()
在我的控制器中始终是 null
(工具栏也注意到,没有注册会话)。注销时,会话在那里,但监听器中的逻辑被跳过。我尝试过优先考虑以确保没有其他听众干扰。
看起来,已经注册该事件会终止会话(即使 onKernelRequest 为空),这很难相信。
我错过了什么?
会话由 Symfony\Component\FrameworkBundle\EventListener\SessionListener
侦听器在 kernel.request
事件上创建(优先级为 128)。
此事件具有特定行为:如果侦听器设置响应,"the process skips directly to the kernel.response event" 引用 the documentation。我怀疑它可能会导致问题。
尝试将您的监听器的优先级设置为 < 0(我让您尝试了很多次),并请检查探查器 "Events" 部分 (/_profiler/latest?panel=events
).
找到解决方案 - 问题是在构造函数中注入 twig-environment - 没有树枝一切都按预期工作。我想,在此阶段加载 twig-environment 会对会话产生影响(比如过早加载)。 我将侦听器移至 onKernelController 并对其进行了修改:
<?php
namespace App\EventListener;
use App\Entity\Company;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
class ShopListener implements EventSubscriberInterface
{
/** @var EntityManagerInterface */
protected $em;
/** @var Environment */
protected $twig;
public function __construct(EntityManagerInterface $entityManager, Environment $twig)
{
$this->em=$entityManager;
$this->twig=$twig;
}
public function onKernelController(ControllerEvent $controllerEvent)
{
if($controllerEvent->isMasterRequest()===false) {
return;
}
/** @var Request $request */
$request=$controllerEvent->getRequest();
$subDomain = $request->attributes->get('domain');
if($subDomain===null) {
return;
}
$company=$this->em->getRepository(Company::class)->findOneBy([
'subDomain' => $subDomain,
]);
if($company instanceof Company && $company->shopIsOnline()) {
$request->attributes->set('company',$company);
return;
}
$controllerEvent->setController(
function() {
return new Response($this->twig->render('page/shop_not_found.html.twig'),404);
}
);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => ['onKernelController',128],
];
}
}