我在zf2(骨架)应用程序中配置了数据库会话,以使用文档中所述的典型MySQL数据库。但是,应用程序仅插入会话,它从不更新特定行。因此,每次刷新时都会创建一个新会话,并且无法检索以前存储的信息。
我的配置如下:
global.php
-------------------
'session_config' => array
(
'cache_expire' => 2419200,
'cookie_lifetime' => 2419200,
'gc_maxlifetime' => 2419200,
'cookie_path' => '/',
'cookie_secure' => TRUE,
'remember_me_seconds' => 2419200,
'use_cookies' => true,
)
我的会话表创建如下(数据库用户有select,insert和amp; update privs):
CREATE TABLE `sessions`
(
`id` char(32) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL,
`modified` int(11) DEFAULT NULL,
`lifetime` int(11) DEFAULT NULL,
`data` text,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
我的数据库会话在Application / Module.php中的工厂闭包中配置:
public function getServiceConfig()
{
return array
(
'factories' => array
(
// Sessions
'session_manager' => function($serviceManager)
{
$sessionOptions = new DbTableGatewayOptions();
$sessionOptions->setDataColumn('data')
->setIdColumn('id')
->setModifiedColumn('modified')
->setLifetimeColumn('lifetime')
->setNameColumn('name');
$dbAdapter = $serviceManager->get('utils-db');
$sessionTableGateway = new TableGateway('sessions', $dbAdapter);
$sessionGateway = new DbTableGateway
($sessionTableGateway, $sessionOptions);
$config = $serviceManager->get('config');
$sessionConfig = new SessionConfig();
$sessionConfig->setOptions($config['session_config']);
$sessionManager = new SessionManager($sessionConfig);
$sessionManager->setSaveHandler($sessionGateway);
return $sessionManager;
},
...
...
),
);
}
会话在onBootstrap方法中启动:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$serviceManager = $e->getApplication()->getServiceManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$sessionManager = $serviceManager->get('session_manager');
$sessionManager->start();
Container::setDefaultManager($sessionManager);
...
}
我可以从概念上理解zf2可以写入/插入到会话中,但它既不能选择特定行,也不能找到它无法更新的特定行。所以我挖到了Zend \ Session \ SaveHandler并在DbTableGateway类中找到了它:
/**
* Write session data
*
* @param string $id
* @param string $data
* @return bool
*/
public function write($id, $data)
{
$data = array(
$this->options->getModifiedColumn() => time(),
$this->options->getDataColumn() => (string) $data,
);
$rows = $this->tableGateway->select(array(
$this->options->getIdColumn() => $id,
$this->options->getNameColumn() => $this->sessionName,
));
if ($row = $rows->current()) {
return (bool) $this->tableGateway->update($data, array(
$this->options->getIdColumn() => $id,
$this->options->getNameColumn() => $this->sessionName,
));
}
$data[$this->options->getLifetimeColumn()] = $this->lifetime;
$data[$this->options->getIdColumn()] = $id;
$data[$this->options->getNameColumn()] = $this->sessionName;
return (bool) $this->tableGateway->insert($data);
}
显然基于条件,如果为真,它将更新,如果不是,则在下面进行插入:
if ($row = $rows->current()) {
return (bool) $this->tableGateway->update($data, array(
$this->options->getIdColumn() => $id,
$this->options->getNameColumn() => $this->sessionName,
));
}
对我来说奇怪的是行
if ($row = $rows->current()) {
变量$ row似乎没有在上面设置,但$ rows确实以正确的select语句结束:
SELECT `sessions`.* FROM `sessions` WHERE `id` = :where1 AND `name` = :where2
id is set correctly
name is set correctly
我无法弄清楚为什么我无法更新我的观点。顺便说一句,我可以很好地从应用程序中的会话中读取数据。但是一旦页面刷新,所有数据都消失了。
答案 0 :(得分:1)
如果您没有通过HTTPS运行应用程序完全,则应将会话配置选项cookie_secure
更改为false
(或省略它 - 默认为{{1 }})。当false
设置为cookie_secure
时,Cookie将仅通过HTTPS发送。
在HTTP请求中,这将导致为每个请求创建一个新会话,因为请求中不存在会话cookie。