如何使用Zend 2保存处理程序DbTableGateway?

时间:2016-07-12 22:09:31

标签: php session zend-framework

Zend\Session Save Handler教程为DbTableGateway提供了一个示例,在该示例中,他们使用未定义的$ adapter变量创建TableGateway。我想使用处理程序将Session Manager(从教程的上一页)绑定到我的数据库中的会话存储表。我怎么能这样做?

我猜代码看起来应该是这样的吗?

class Module implements AutoloaderProviderInterface, ConfigProviderInterface
{
    public function onBootstrap(MvcEvent $e) {
        $eventManager        = $e->getApplication()->getEventManager();

        // create the session manager
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
        $this->bootstrapSession($e);
    }

    public function bootstrapSession($e)
    {
        $session = $e->getApplication()
            ->getServiceManager()
            ->get('Zend\Session\SessionManager');
        $tableGateway = new TableGateway('session', $adapter); // somehow define this somewhere?
        $saveHandler  = new DbTableGateway($tableGateway, new DbTableGatewayOptions());
        $session->setSaveHandler($saveHandler);
        $session->start();

        $container = new Container('initialized');
        if (!isset($container->init)) {
            $serviceManager = $e->getApplication()->getServiceManager();
            $request        = $serviceManager->get('Request');

            $session->regenerateId(true);
            $container->init          = 1;
            $container->remoteAddr    = $request->getServer()->get('REMOTE_ADDR');
            $container->httpUserAgent = $request->getServer()->get('HTTP_USER_AGENT');

            $config = $serviceManager->get('Config');
            if (!isset($config['session'])) {
                return;
            }

            $sessionConfig = $config['session'];
            if (isset($sessionConfig['validators'])) {
                $chain   = $session->getValidatorChain();

                foreach ($sessionConfig['validators'] as $validator) {
                    switch ($validator) {
                        case 'Zend\Session\Validator\HttpUserAgent':
                            $validator = new $validator($container->httpUserAgent);
                            break;
                        case 'Zend\Session\Validator\RemoteAddr':
                            $validator  = new $validator($container->remoteAddr);
                            break;
                        default:
                            $validator = new $validator();
                    }

                    $chain->attach('session.validate', array($validator, 'isValid'));
                }
            }
        }
    }

    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Zend\Session\SessionManager' => function ($sm) {
                    $config = $sm->get('config');
                    if (isset($config['session'])) {
                        $session = $config['session'];

                        $sessionConfig = null;
                        if (isset($session['config'])) {
                            $class = isset($session['config']['class'])  ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
                            $options = isset($session['config']['options']) ? $session['config']['options'] : array();
                            $sessionConfig = new $class();
                            $sessionConfig->setOptions($options);
                        }

                        $sessionStorage = null;
                        if (isset($session['storage'])) {
                            $class = $session['storage'];
                            $sessionStorage = new $class();
                        }

                        $sessionSaveHandler = null;
                        if (isset($session['save_handler'])) {
                            // class should be fetched from service manager since it will require constructor arguments
                            $sessionSaveHandler = $sm->get($session['save_handler']);
                        }

                        $sessionManager = new SessionManager($sessionConfig, $sessionStorage, $sessionSaveHandler);
                    } else {
                        $sessionManager = new SessionManager();
                    }
                    Container::setDefaultManager($sessionManager);
                    return $sessionManager;
                },
            ),
        );
    }

    /***************************************************************************************************
     * Returns the location of the module.config.php file. This function is used by the Zend Framework
     * underneath the hood.
     ***************************************************************************************************/
    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    /***************************************************************************************************
     * Returns the Zend StandardAutoLoader which contains the directory structure of the module source
     * folder.
     ***************************************************************************************************/
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }
}

2 个答案:

答案 0 :(得分:2)

我有这个代码用于将会话保存到db表。

'service_manager' => array(
    'factories' => array(
        'Zend\Session\SessionManager' => function (\Zend\ServiceManager\ServiceManager $sm) {
            $sessionConfig = new \Zend\Session\Config\SessionConfig();
            $sessionConfig->setOptions(
                array(
                    'use_cookies' => true,
                    'name' => 'ed2',
                    'gc_maxlifetime' => 1728000
                )
            );

            /* @var $adapter \Zend\Db\Adapter\Adapter */
            $adapter = $sm->get('Zend\Db\Adapter\Adapter');
            $tableGateway = new \Zend\Db\TableGateway\TableGateway('session', $adapter);
            $saveHandler  = new \Common\Session\SaveHandler\DbTableGateway(
                $tableGateway,
                new \Zend\Session\SaveHandler\DbTableGatewayOptions()
            );

            $sessionManager = new \Zend\Session\SessionManager($sessionConfig);
            $sessionManager->setSaveHandler($saveHandler);
            $sessionManager->start();
            return $sessionManager;
        },
    )
)

db

的配置
'db' => array(
    'driver'    => 'Pdo_Mysql',
    'database'  => 'release',
    'username'  => 'username',
    'password'  => 'password',
    'hostname'  => '127.0.0.1',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    )
),
'service_manager' => array(
    'factories' => array(
        'Zend\Db\Adapter\Adapter' => function (\Zend\ServiceManager\ServiceManager $serviceManager) {
            $adapterFactory = new Zend\Db\Adapter\AdapterServiceFactory();
            $adapter = $adapterFactory->createService($serviceManager);

            Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);

            return $adapter;
        }
    )
)

答案 1 :(得分:0)

答案结果就像是新手的回答:

由于newage编辑了他的答案以包含db适配器,我已经接受了它作为正确的答案。其余的只是我的实现:

您可以从bootstrapSession方法中删除所有TableGateway和savehandler逻辑,并将其放在getServiceConfig方法中。

将Adapter的定义添加到getServiceConfig中的'factories'数组,然后修改'Zend\Session\SessionManager'函数以包含Adapter,TableGateway和save handler。这就是新的getServiceConfig的样子:

public function getServiceConfig()
{
    return array(
        'factories' => array(

            // New code here
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
            // New code here

            'Zend\Session\SessionManager' => function ($sm) {
                $config = $sm->get('config');
                if (isset($config['session'])) {
                    $session = $config['session'];

                    $sessionConfig = null;
                    if (isset($session['config'])) {
                        $class = isset($session['config']['class'])  ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
                        $options = isset($session['config']['options']) ? $session['config']['options'] : array();
                        $sessionConfig = new $class();
                        $sessionConfig->setOptions($options);
                    }

                    $sessionStorage = null;
                    if (isset($session['storage'])) {
                        $class = $session['storage'];
                        $sessionStorage = new $class();
                    }

                    $sessionSaveHandler = null;
                    if (isset($session['save_handler'])) {
                        // class should be fetched from service manager since it will require constructor arguments
                        $sessionSaveHandler = $sm->get($session['save_handler']);
                    }
                    $sessionManager = new SessionManager();
                }

                // New code here
                /* @var $adapter \Zend\Db\Adapter\Adapter */
                $adapter = $sm->get('Zend\Db\Adapter\Adapter');
                $tableGateway = new TableGateway('mytablename', $adapter);
                $saveHandler  = new DbTableGateway($tableGateway, new DbTableGatewayOptions());
                $sessionManager->setSaveHandler($saveHandler);
                // New code here

                Container::setDefaultManager($sessionManager);
                return $sessionManager;
            },
        ),
    );
}

然后将数据库连接信息添加到模块的配置文件中:

return array(
    // ...
    'db' => array(
        'driver'         => 'Pdo',
        'dsn'            => 'mysql:dbname=mydbname;host=mydbhost;port=xxxx',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
        'username'       => 'dbusername',
        'password'       => 'dbpassword',
    ),
);