如何使用 Zend 2 保存处理程序 DbTableGateway?
How to use Zend 2 save handler DbTableGateway?
Zend\Session Save Handler tutorial gives an example for DbTableGateway in which they create a TableGateway with an undefined $adapter variable. I want to use the handler to tie the Session Manager(从教程的上一页)到我的数据库中的会话存储table。我该怎么做?
我猜代码应该是这样的?
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__,
),
),
);
}
}
我有这段代码可以将会话保存到数据库 table。
'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;
}
)
)
答案竟然和newage的答案一样:
自从 newage 编辑了他的答案以包含数据库适配器后,我就接受了它作为正确答案。剩下的只是我的实现:
你可以把bootstrapSession方法中所有的TableGateway和savehandler逻辑去掉,放在getServiceConfig方法中。
将 Adapter 的定义添加到 getServiceConfig 中的 'factories'
数组,然后修改 'Zend\Session\SessionManager'
函数以包含 Adapter、TableGateway 和保存处理程序。这就是新的 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',
),
);
Zend\Session Save Handler tutorial gives an example for DbTableGateway in which they create a TableGateway with an undefined $adapter variable. I want to use the handler to tie the Session Manager(从教程的上一页)到我的数据库中的会话存储table。我该怎么做?
我猜代码应该是这样的?
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__,
),
),
);
}
}
我有这段代码可以将会话保存到数据库 table。
'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;
}
)
)
答案竟然和newage的答案一样:
自从 newage 编辑了他的答案以包含数据库适配器后,我就接受了它作为正确答案。剩下的只是我的实现:
你可以把bootstrapSession方法中所有的TableGateway和savehandler逻辑去掉,放在getServiceConfig方法中。
将 Adapter 的定义添加到 getServiceConfig 中的 'factories'
数组,然后修改 'Zend\Session\SessionManager'
函数以包含 Adapter、TableGateway 和保存处理程序。这就是新的 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',
),
);