Как внедрить @request_stack или @request в прослушиватель

У меня есть этот слушатель:

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\Request;

class ControllerListener
{
    public function onKernelController( FilterControllerEvent $event, Request $request )
    {
        if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
            $controllers = $event->getController();
            if (is_array( $controllers )) {
                $controller = $controllers[0];
                if (is_object( $controller )) {
                    if (method_exists( $controller, 'parControl' )) {
                        $controller->parControl(
                            $controller->getRequest(),
                            $controller->getRequest()->get( 'action' ),
                            $controller->getRequest()->get( 'context' ),
                            $controller->getRequest()->get( 'page' ),
                            $controller->getRequest()->get( 'case' ),
                            $controller->getRequest()->get( 'subset' )
                        );
                    }

                    if (method_exists( $controller, 'adminProjectControl' )) {
                        // to this method I need to pass Request $request  
                        $controller->adminProjectControl($request);
                    }

                    if (method_exists( $controller, 'accessControl' )) {
                        $controller->accessControl();
                    }
                }
            }
        }
    }

    public function onKernelResponse( FilterResponseEvent $event )
    {
        Utilities::flashDebugLoginMessage();
    }
}

И это определяется как услуга в services.yml:

pdone.listener.preexecute:
    class: GroupDCA\PDOneBundle\Listener\ControllerListener
    arguments: [@request]
    public: true
    scope: request
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
        - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }

Но я должен сделать что-то не так, так как я получил эти три ошибки:

ContextErrorException в ControllerListener.php, строка 12: Catchable Fatal Error: Аргумент 2, переданный в GroupDCA\PDOneBundle\Listener\ControllerListener::onKernelController(), должен быть экземпляром Symfony\Component\HttpFoundation\Request, указанная строка

ContextErrorException в ControllerListener.php, строка 12: Catchable Fatal Error: Аргумент 2, переданный в GroupDCA\PDOneBundle\Listener\ControllerListener::onKernelController(), должен быть экземпляром Symfony\Component\HttpFoundation\Request, указанная строка

LogicException в строке bootstrap.php.cache 3118: ни один слушатель события «kernel.exception» не установил ответ

Итак, как мне ввести запрос слушателю? Могу ли я сделать это? Я также прочитал этот пост, но не понял, как сделай это.


person ReynierPM    schedule 14.04.2015    source источник
comment
Каждому слушателю передаются 3 аргумента - отправляемый объект события (FilterControllerEvent), имя события (kernel.controller) и диспетчер событий (@event_dispatcher) - вот почему вы получаете сообщение об ошибке, что второй аргумент является строкой, поскольку это название события. Это может быть полезно, если вы хотите сцепить событие без необходимости вводить @event_dispatcher в каждого слушателя/подписчика.   -  person qooplmao    schedule 15.04.2015


Ответы (2)


FilterControllerEvent уже дает вам доступ к запросу:

public function onKernelController(FilterControllerEvent $event)
{
    $request = $event->getRequest();       

    // ...
}

Если вам нужен запрос в прослушивателях, где событие не предоставляет запрос, всегда используйте стек запросов:

use Symfony\Component\HttpFoundation\RequestStack;

class MyService
{
    private $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public function doSomething()
    {
        $request = $this->requestStack->getCurrentRequest();

        // ...
    }
}

Внедрение запроса устарело и будет удалено. Стек запросов — это правильный путь. Также не используйте прицел request.

person Jakub Zalas    schedule 15.04.2015

Вы передаете объект запроса конструктору ControllerListener из определения службы, а не методу onKernelController.

Вместо этого выполните:

protected $request;

public function __construct (Request $request) {

    $this->request = $request;
}

Что должно решить вашу проблему и сделать объект запроса доступным.

person Richard    schedule 15.04.2015
comment
Вместо внедрения службы @request рекомендуется внедрить @request_stack, а затем получить запрос через $requestStack->getCurrentRequest(). Это также означает, что вам не нужно менять область действия службы на request. - person qooplmao; 15.04.2015
comment
Это не правильно. Вы не должны вводить запрос напрямую, как предложил Qoop. Смотрите мой ответ. - person Jakub Zalas; 15.04.2015