我学习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));
}
它返回闭包。
我认为此步骤尚未初始化请求。
我的任务是提供授权服务,这应将经过身份验证的用户保存到会话中。
请告诉我,如何正确获取请求和会话实例?
也许,我不理解zend表达方式是如何工作的吗?
答案 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时就遇到了这个问题。需要一点时间来适应,所以我认为仍然可以回答它。