如何在容器中获得请求和会话?

时间:2018-12-13 21:08:12

标签: php zend-expressive

我学习zend表现力,并且对工厂有一些疑问。

因此,我可以在中间件中进行会话:

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

但是,如果要创建具有会话依赖性的自定义服务,则需要将会话实例放入工厂。

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

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

当我尝试从容器获取请求实例时:

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

它返回闭包。

enter image description here

我认为此步骤尚未初始化请求。

我的任务是提供授权服务,这应将经过身份验证的用户保存到会话中。

请告诉我,如何正确获取请求和会话实例?

也许,我不理解zend表达方式是如何工作的吗?

2 个答案:

答案 0 :(得分:1)

我不清楚您在授权服务上可能会遇到的限制,但也许您是用错误的方式来处理问题。

documentation与示例身份验证样例一起嵌套中间件可能会有用

但不了解项目的具体细节,您可以了解有关zend表现力here中会话持久性的更多信息,或在zend表现力上下文here中查看身份验证适配器

答案 1 :(得分:0)

不能session获取ContainerInterface

会话是您请求生命周期的一部分。如果您使用的是zend-expressive-session,则可以从处理程序获取会话,因为该会话将通过

附加到Request
$request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE)

因此,如果您的服务需要使用会话,则需要从容器中注入该会话。基本上,您应该具有以下内容:

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;
    }
}

在您的处理程序中,然后适当地注入会话:

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();
    }
}

这当然是一个比较老的问题,但是我刚看到它,当我第一次进入Expressive时就遇到了这个问题。需要一点时间来适应,所以我认为仍然可以回答它。