Symfony - использование ветки в сеансе onKernelRequest убивает - PullRequest
3 голосов
/ 02 июня 2019

У меня странная проблема в 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 пуст), что трудно поверить.Чего мне не хватает?

Ответы [ 2 ]

2 голосов
/ 05 июня 2019

Нашел решение - проблема заключается во внедрении среды ветки в конструктор - без ветки все работает как положено. Я предполагаю, что загрузка среды ветки на этом этапе делает что-то с сеансом (например, загрузка слишком рано). Я переместил слушатель в 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],
        ];
    }
}
2 голосов
/ 03 июня 2019

Сеанс создается Symfony\Component\FrameworkBundle\EventListener\SessionListener слушателем, также для события kernel.request (приоритет 128).
Это событие имеет определенное поведение: если слушатель задает Response, процесс переходит непосредственно к ядру.Ответное событие "Цитировать Документация .Я подозреваю, что это может вызвать проблемы.
Попробуйте установить для слушателя приоритет <0 (я получаю, что вы пробовали много), и, пожалуйста, проверьте порядок в разделе «События» профилировщика (<code>/_profiler/latest?panel=events).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...