0

I learn zend expressive and I have some questions about factories.

So, I can get a session in middleware:

...
/** @var Zend\Expressive\Session\LazySession $session */
$session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
...

However, if I want to create a custom service with session dependency I need to get session instance into factory.

class AuthServiceFactory
{
    public function __invoke(ContainerInterface $container): HttpAuthService
    {
        // get instance $userRepository
        // get instance $session

        return new HttpAuthService(
            $userRepository,
            $session
        );
    }
}

When I try to get request instance from container:

public function __invoke(ContainerInterface $container): HttpAuthService
{
    dd($container->get(\Psr\Http\Message\ServerRequestInterface::class));
}

it returns Closure.

enter image description here

I think request is not initialized at this step.

My task is to make a service for authorization, which should save authenticated user to the session.

Tell me, please, how can I get the request and session instances correctly?

Maybe, Do I not understand how zend expressive works?

Nepster
  • 144
  • 6

2 Answers2

1

I'm not clear on the constraints you may have on your authorization service, but perhaps you are approaching things the wrong way.

This documentation on nesting middleware with a sample authentication piece might be helpful

But not knowing the specifics of your project, you can learn more about session persistence within zend expressive here or take a look at authentication adapters in a zend expressive context here

  • I'm trying to learn this documentation. Thanks you. However, I have a question, how to get session instance from the container? – Nepster Dec 15 '18 at 20:41
0

You are not able to get the session from the ContainerInterface.

The Session is part of the Lifecycle of your Request. If you're using zend-expressive-session you'll be able to get the Session from your Handlers, as it will be attached to the Request via

$request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE)

So if your service needs to use the session you'll need to inject this from your container. Basically you should have something like this:

class SomeService
{
    /** @var SessionInterface $session **/
    private $session;

    public function __construct(SomeDependency $dep) {
        //...
    }

    public function thatNeedsASession()
    {
        if (false === $this->session instanceof SessionInterface)
        {
            throw RuntimeException('Bro, inject that session thingy!');
        }

        //... use session here
    }

    public function setSession(SessionInterface $session) 
    {
        $this->session = $session;
    }
}

Form your Handler you'd then inject the Session appropriately:

class SomeHandler
{
    /** @var SomeService $service **/
    private $service;

    public function __construct(SomeService $service)
    {
        $this->service = $service;
    }

    public function handle(ServerRequestInterface $request) : ResponseInterface
    {
        $session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);

        $this->service->setSession($session);

        // You're now able to properly use your service
        $this->service->thatNeedsASession();
    }
}

This certainly is an older question but I just saw it and I had this question myself when I first stepped into Expressive. Takes a bit of getting used to so I suppose it's good to still answer it.

Sam
  • 16,435
  • 6
  • 55
  • 89