How to enter @request into a service?

When I try to embed @request in any of my services, I get this exception:

ScopeWideningInjectionException: Extension scope Extension Injection detected: The definition of "service.navigation" refers to the request request, which refers to a narrower space. It is generally safer to move “service.navigation” to the “request” area or, alternatively, rely on the provider template by entering the container itself and requesting a “request” service every time you need it. In rare special cases, however, this may not be necessary, then you can set the link to strict = false to get rid of this error.

What is the best way to continue? Should I try to set this strict=false and how, or should I NOT enter the request service, but pass it to the service through my controller every time I call the functions I need?

Another possibility would be to add a kernel and take it from there, but in my service I use only @router and @request, so injecting the whole kernel will be irrational.

Thank!

+50
dependency-injection symfony service
Feb 17 2018-12-17T00:
source share
8 answers

I think there may have been some misunderstanding of what the official documentation says. In most cases, you want to insert a request directly with the scope="request" attribute in the service element. This will accelerate the expansion of the scope.

 <service id="zayso_core.openid.rpx" class="Zayso\CoreBundle\Component\OpenidRpx" public="true" scope="request"> 

or yml

 zayso_core.openid.rpx: class: Zayso\CoreBundle\Component\OpenidRpx public: true scope: request 

This is only in special cases, such as Twig extensions, where you need to insert a container.

And the core is not even mentioned on the page in the area. Kernel injection is much worse (conceptually) than container injection.

UPDATE: for S2.4 and newer use @Blowski answer below.

+31
Feb 18 2018-12-18T00:
source share
— -

In Symfony 2.4, this has changed. Now you can enter the service "request_stack".

For example:

 use Symfony\Component\HttpFoundation\RequestStack; class MyService { protected $request; public function setRequest(RequestStack $request_stack) { $this->request = $request_stack->getCurrentRequest(); } } 

In your config.yml:

 services: my.service: class: Acme\DemoBundle\MyService calls: - [setRequest, ["@request_stack"]] 

Full documentation is here: http://symfony.com/blog/new-in-symfony-2-4-the-request-stack

+96
Dec 10 '13 at 18:56
source share

The best way I found the service was to use the request service, rather than relying on the entire container and still not require a request area, to make the RequestInjector service that accepts the container. then you enter this into a service that wants to use a request object

 class RequestInjector{ protected $container; public function __construct(Container $container){ $this->container = $container; } public function getRequest(){ return $this->container->get('request'); } } class SomeService{ protected $requestInjector; public function __construct(RequestInjector $requestInjector){ $this->requestInjector = $requestInjector; } } 

for services.yml

 request_injector: class: RequestInjector public: false arguments: ['@service_container'] some_service: class: SomeService arguments: ['@request_injector'] 
+6
Jul 19 '12 at 19:03
source share

The way I found, and I'm sure this is probably not the best way (not even recommended), is to define the query service as synthetic.

Edit: Indeed, this is not recommended, because it disables checking the level of visibility of the area. This thread contains a good explanation of why Symfony throws this exception: http://groups.google.com/group/symfony-devs/browse_thread/thread/a7207406c82ef07a/e2626c00f5cb9749

In services.xml :

 <service id="request" synthetic="true" /> <service id="my_service" class="......"> <argument type="service" id="request" /> </service> 

Strike>

In docs, it’s better to place your service in the request area or just enter the service container.

+5
Feb 17 '12 at 17:55
source share

NB: This answer was written in 2012 when Symfony 2.0 came out, and then it was a good way to do it! Please do not go down :)




Today I myself experienced the same problem, so here are my 5 cents. According to official documentation , it is usually not required to enter request into your services. In your service class, you can pass the kernel container (injecting is not a big overhead as it sounds), and then access the request as follows:

 public function __construct(\AppKernel $kernel) { $this->kernel = $kernel; } public function getRequest() { if ($this->kernel->getContainer()->has('request')) { $request = $this->kernel->getContainer()->get('request'); } else { $request = Request::createFromGlobals(); } return $request; } 

This code also works great when accessing a service in the CLI (for example, during unit testing).

+5
Feb 17 '12 at 18:45
source share

If you cannot use RequestStack directly, you can create a factory service that returns the current request using RequestStack.

 # services.yml app.request: class: Symfony\Component\HttpFoundation\RequestStack factory: [ @request_stack, getCurrentRequest ] 

You can then access the current request using the app.request service.

+4
Sep 10 '15 at 19:47
source share

I think it’s more important to focus on getting the request instead of setting it up. I would do something similar to @Blowski's solution, except for using getter. This is very similar to an example.

 namespace Acme\HelloBundle\Newsletter; use Symfony\Component\HttpFoundation\RequestStack; class NewsletterManager { protected $requestStack; public function __construct(RequestStack $requestStack) { $this->requestStack = $requestStack; } protected function getRequest() { return $this->requestStack->getCurrentRequest(); } public function foo() { $request = $this->getRequest(); // Do something with the request } } 

And your services.yml configuration file.

 services: newsletter_manager: class: Acme\HelloBundle\Newsletter\NewsletterManager arguments: ["@request_stack"] 

Now you are always sure that you are receiving the correct request, and you do not need to worry about tuning / re-setting the request.

+1
May 23 '16 at 16:10
source share

As @simshaun claims to be the best practice to place its service in the request area. This makes the purpose of the service understandable.

Note that will make your service unavailable in other areas, such as the command line. However, if your service depends on the request, you still should not use it on the command line (because there is no request on the command line.

-one
Feb 22 2018-12-22T00:
source share



All Articles