我正在使用一个 PHP 会话管理器类来处理 MongoDB 中的用户会话,但它不起作用,我终生无法弄清楚原因。会话变量设置成功,但不会持续到其他页面。与 MongoDB 的连接不是问题。我已经确定这个问题与 . session_set_save_handler
,因为如果我注释掉这个函数,原生 PHP 会话处理工作正常。
在此先感谢您的帮助。
...
require('database.class.php');
class SessionManager {
const COLLECTION = 'sessions';
const SESSION_TIMEOUT = 600;
const SESSION_LIFESPAN = 3600;
const SESSION_NAME = 'mongosessid';
const SESSION_COOKIE_PATH = '/';
const SESSION_COOKIE_DOMAIN = '';
private $_mongo;
private $_collection;
private $_currentSession;
public function __construct() {
$this->_mongo = DBConnection::instantiate();
$this->_collection = $this->_mongo->getCollection(SessionManager::COLLECTION);
register_shutdown_function('session_write_close');
session_set_save_handler(
array(&$this, 'open'),
array(&$this, 'close'),
array(&$this, 'read'),
array(&$this, 'write'),
array(&$this, 'destroy'),
array(&$this, 'gc')
);
//Set session garbage collection period
ini_set('session.gc_maxlifetime', SessionManager::SESSION_LIFESPAN);
//Set session cookie config
session_set_cookie_params(
SessionManager::SESSION_LIFESPAN,
SessionManager::SESSION_COOKIE_PATH,
SessionManager::SESSION_COOKIE_DOMAIN
);
//Replace 'PHPSESSID' with 'mongosessid' as the session name
session_name(SessionManager::SESSION_NAME);
session_cache_limiter('nocache');
session_start();
}
public function open($path, $name) {
return true;
}
public function close() {
return true;
}
public function read($sessionId) {
$query = array('session_id' => $sessionId,
'timedout_at' => array('$gte' => time()),
'expired_at' => array('$gte' => time() - SessionManager::SESSION_LIFESPAN)
);
$result = $this->_collection->findOne($query);
$this->_currentSession = $result;
if (!isset($result['data'])) {
return '';
}
return $result['data'];
}
public function write($sessionId, $data) {
$expired_at = time() + self::SESSION_TIMEOUT;
$new_obj = array('data' => $data,
'timedout_at' => time() + SessionManager::SESSION_TIMEOUT,
'expired_at' => (empty($this->_currentSession)) ? time() + SessionManager::SESSION_LIFESPAN : $this->_currentSession['expired_at']
);
$query = array('session_id' => $sessionId);
$this->_collection->update($query,
array('$set' => $new_obj),
array('$upsert' => TRUE)
);
}
public function destroy($sessionId) {
$this->_collection->remove(array('session_id' => $sessionId));
return TRUE;
}
public function gc() {
$query = array('expired_at' => array('$lt' => time()));
$this->_collection->remove($query);
return TRUE;
}
}
$session = new SessionManager();
?>