0

I would like to access request object outside of the handler.

What I'm trying to achieve, is to have a factory class, which based on the values from the request, will setup some class.

Unfortunately code below (in the factory class) doesn't provide a proper request object.

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null, ServerRequestInterface $request): AbstractAttributeValidator
    {
        /** @var ServerRequestInterface $request */
        $request = $container->get(ServerRequestInterface::class);

I don't seen anything in the documentation.

Could you suggest something? Or should I approach the problem in different way?

Pawel
  • 466
  • 1
  • 7
  • 20
  • (I'm new to Zend) but can you not auto wire (ServerRequestInterface $request) in your parameter ? – Dylan KAS Jul 11 '19 at 11:37
  • Not really. Zend ServiceManager calls factories in this way ```$factory($this->creationContext, $resolvedName, $options)```, so there is no place for additional parameters. – Pawel Jul 11 '19 at 11:47
  • Could you be more specific? Why do you need that? I encountered a similar situation some time ago. I was working on a hybrid application (had both zend expressive and legacy code - access folder/index.php). I managed to create the same workflow by "simulating" the zend expressive workflow. The logic is similar to zend expressive config directory (containter.php and pipeline.php) – Razvan Ionascu Nov 06 '19 at 08:57

2 Answers2

1

You can not inject the request into a service. The container is unaware of the request. I'm not sure what you are actually trying to achieve but there are workarounds.

For example, you can create a middleware, inject the service class into it and inject the request into that service class with a setRequest middleware. But that feels a bit hacky.

Another workaround I use is adding a MyService::doSomethingWithRequest(ServerRequestInterface $request). This way the service class can do it's things with the request after you got it from the container.

Since you need a request, it sounds what you might need is a middleware and do some logic in there instead of a service class. An easy example might be authentication middleware.

But it would help if you describe in what kind of service you need the request.

xtreamwayz
  • 1,285
  • 8
  • 10
  • Hi. Based on the current path (first segment of the path), in the factory I want to build some services/repositories which will be injected into the handler. I think I found some solution to it, and in a factory I'm getting UrlHelper from the container, which gives me matching Route. – Pawel Jul 12 '19 at 08:19
0

For the design matters it is better not to inject request into a non-handler service. Handler is a layer that do is responsible for handlig request alone. If you need to do something with parameters that came with request, you need to pass parameters alone, not a whole request.

Nevertheless if you are about to modify a whole request/response - for authentication headers, cookies, csrf etc, you should be interested in a middleware pattern. PSR-15 middlewares are well designed and dedicated to work as request/response modifiers. Also Zend/Laminas have support for them within Expressive and Mezzio solutions.

yergo
  • 4,761
  • 2
  • 19
  • 41