Php 会话容器中的对象变量在引导过程中始终为null

Php 会话容器中的对象变量在引导过程中始终为null,php,zend-framework2,zend-session,Php,Zend Framework2,Zend Session,我在应用程序模块的引导程序中实现了一个逻辑,如果用户未签名,该逻辑将重定向到登录页面。我有 class Module { public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $moduleRouteListener = new ModuleRouteListener();

我在应用程序模块的引导程序中实现了一个逻辑,如果用户未签名,该逻辑将重定向到登录页面。我有

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);

        $session = new Container('signin');

        if (!isset($session->member)){
           $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this,'routeMatched'), -100);            
        }
    }

    public function routeMatched(MvcEvent $e)
    {
        $match = $e->getRouteMatch();

        // No route match, this is a 404
        if (!$match instanceof RouteMatch) {
            return;
        }
        $list = array('login', 'signin', 'upload');
        // Route is whitelisted
        $name = $match->getMatchedRouteName();
        if (in_array($name, $list)) {
            return;
        }

        // Redirect to the user login page, as an example
        $router   = $e->getRouter();
        $url      = $router->assemble(array(), array(
            'name' => 'signin'
        ));

        $response = $e->getResponse();
        $response->getHeaders()->addHeaderLine('Location', $url);
        $response->setStatusCode(302);

        return $response;        
    }
}
如下所示,
onBootstrap
中的代码将检查会话容器是否未设置
member
变量,如果未设置,则附加事件路由,该事件路由将根据当前路由是否为白名单在内部处理操作

        $session = new Container('signin');
        if (!isset($session->member)) ...
这里的问题是
$session->member
总是得到
null
。我在控制器内的登录操作中分配此变量,如下所示

            if ($data->authenticate($member->email, $member->password)){
                $session = new Container('signin');
                $session->member = $member;
                return $this->redirect()->toRoute('member-control-panel');                    
            }else{
                $view->setVariable('error', 'Could not verify user/password');
            }
                $session = new Container('signin');
                //$session->member = $member; //removed
                $session->email= $member->email; //New
        $session = new Container('signin');

        if (!isset($session->email)){
           $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this,'routeMatched'), -100);            
        }
这里有什么问题

更新:

我按照威尔茨在回答中的建议做了修改。它仍然不起作用,但我稍微修改了代码以存储标量值(email)而不是对象(member)。现在它正在工作,所以问题是为什么会话容器不存储对象,而只存储标量变量?

在我的签名行动中,我做了这样的改变

            if ($data->authenticate($member->email, $member->password)){
                $session = new Container('signin');
                $session->member = $member;
                return $this->redirect()->toRoute('member-control-panel');                    
            }else{
                $view->setVariable('error', 'Could not verify user/password');
            }
                $session = new Container('signin');
                //$session->member = $member; //removed
                $session->email= $member->email; //New
        $session = new Container('signin');

        if (!isset($session->email)){
           $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this,'routeMatched'), -100);            
        }
在这样的引导程序中

            if ($data->authenticate($member->email, $member->password)){
                $session = new Container('signin');
                $session->member = $member;
                return $this->redirect()->toRoute('member-control-panel');                    
            }else{
                $view->setVariable('error', 'Could not verify user/password');
            }
                $session = new Container('signin');
                //$session->member = $member; //removed
                $session->email= $member->email; //New
        $session = new Container('signin');

        if (!isset($session->email)){
           $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this,'routeMatched'), -100);            
        }

正确地处理会话所涉及的不仅仅是将变量转储到
容器
实例中。会话不能在不序列化对象的情况下存储对象。这意味着您必须在从会话解析它们时再次反序列化它们

使用会话管理器 为了帮助您管理会话存储,ZF2有一个
SessionManager
类,我建议您创建一个
SessionManager
来控制会话变量。你可以在报纸上读到更多

您可以像这样启动会话:

use Zend\Session\SessionManager;
use Zend\Session\Container;

class Module
{
    public function onBootstrap($event)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
        $this->bootstrapSession($event);
    }

    public function bootstrapSession($e)
    {
        $session = $e->getApplication()
                     ->getServiceManager()
                     ->get('Zend\Session\SessionManager');
        $session->start();

        $container = new Container('signin');
    }
}
存储条令实体
如果您的
$member
是一个条令实体,我还建议您阅读

您的应用程序中的会话是否在此时启动?我认为Zend\session\Container将在内部处理您可以写一些关于解决方案的内容吗?您是否建议在事件侦听器中移动检查?为什么?@SolowDeveloper我在我的回答中添加了更多的解释。你能看看我更新的问题吗?这个问题看起来不像是在引导中创建的会话容器,但看起来像是处理会话容器可以处理的标量值和对象值store@SolowDeveloper我更新了我的答案。我意识到错误不在于使用引导事件。您不能像这样直接将对象存储在会话容器中。