我已将会话设置为保存在数据库中。我想在多个子域之间共享同一个会话,但似乎每个子域都会覆盖另一个子域的会话。
例如,我在一个子域中的会话中添加了一些变量,并且它们显示为oky,但是当我访问其他子域时,会话为空。
我使用的课程如下:
<?php
class Nip_Session
{
protected $id;
protected $_lifetime;
protected $db;
protected $table = 'session';
public function __construct()
{
$this->db = Nip_Registry::instance()->get('__DBROOT');
$this->_lifetime = get_cfg_var("session.gc_maxlifetime");
ini_set('session.save_handler', 'user');
register_shutdown_function('session_write_close');
$id = $this->checkRequestId();
$this->setHandlers()->start($id);
}
/**
* Restarts the session, with new optional session id
*
* @param string $id
*/
public function reinitialize($id = false)
{
session_write_close();
$this->setHandlers()->start($id);
}
/**
* Starts the session, with optional session id
*
* @param string $id
*/
protected function start($id = false)
{
if ($id) {
session_id($id);
}
Nip_AutoLoader::instance()->isFatal(false);
session_start();
Nip_AutoLoader::instance()->isFatal(true);
}
/**
* Overrides default session handling functions
*
* @return Session
*/
protected function setHandlers()
{
session_set_save_handler(
array($this, 'open'),
array($this, 'close'),
array($this, 'read'),
array($this, 'write'),
array($this, 'destroy'),
array($this, 'gc')
);
return $this;
}
public function open()
{
return true;
}
public function close()
{
return true;
}
/**
* Public method to return the session id
* @todo implement a verification method ( ex: adding another validation string in the sessionID )
* @return int
*/
public function getId()
{
return session_id();
}
/**
* Gets the session ID from REQUEST
* @return int
*/
public function checkRequestId()
{
if (isset($_REQUEST['session_id'])) {
return $_REQUEST['session_id'];
}
return false;
}
/**
* Fetches session entry from database
*
* @param string $id
* @return mixed
*/
public function read($id)
{
/* @var $result Nip_DBResult */
$query = $this->db->newQuery('select');
$query->from($this->table)
->where('id = ?', $id)
->where('expires > ?', time())
->limit(1);
$result = $this->db->execute($query);
$return = false;
if ($result->numRows()) {
$row = $result->fetchResult();
$return = $this->decodeData($row['data']);
}
return $return;
}
/**
* Stores the surrent session in the database
*
* @param string $id
* @param mixed $data
* @return int
*/
public function write($id, $data)
{
$replace = array();
$replace['id'] = $id;
$replace['data'] = $this->encodeData($data);
$replace['expires'] = time() + $this->_lifetime;
$query = $this->db->newQuery('replace');
$query->table($this->table)
->data($replace);
$result = $this->db->execute($query);
return $this->db->affectedRows();
}
/**
* Destroys current session and deletes it's entry from the database
*
* @param string $id
* @return int
*/
public function destroy($id)
{
$query = $this->db->newQuery("delete");
$query->table($this->table);
$query->where('id = ?', $id);
$query->limit(1);
$query->execute();
return $this->db->affectedRows();
}
/**
* Garbage control. Called by PHP to remove expired entries from the database
* @return int
*/
public function gc()
{
$query = $this->db->newQuery("delete");
$query->table($this->table);
$query->where('expires <= ?', time());
$query->execute();
return $this->db->affectedRows();
}
/**
* @param Nip_DB_Wrapper $db
* @return Nip_Session
*/
public function setDB($db)
{
$this->db = $db;
return $this;
}
/**
* @param int $lifetime
* @return Nip_Session
*/
public function setLifetime($lifetime)
{
if ($lifetime && is_numeric($lifetime)) {
$this->_lifetime = $lifetime;
}
return $this;
}
/**
* Encodes data to be stored
*
* @param mixed $data
* @return string
*/
protected function encodeData($data)
{
return base64_encode($data);
}
/**
* Decodes data to be used
*
* @param string $data
* @return mixed
*/
protected function decodeData($data)
{
return base64_decode($data);
}
/**
* Singleton
*
* @return Nip_Session
*/
static public function instance()
{
static $instance;
if (!($instance instanceof Nip_Session)) {
$instance = new Nip_Session();
}
return $instance;
}
}
我做了一些回音,会话ID是一样的。我在read方法中做了一个var_dump,它似乎从数据库中读取了oky:
string(1484)"X3pJX1JQTk9LeW9fQVBBWk03dnhNMVFKNmxLZk1YdEtIMkNGS3EzdW5Oa0hvUFVaWTZJdHlyMzJUc09MUDUwUFpBZHZXTDZfbzM3SjhSbmp1T3lfVnBkMEdSY0dqQzc ......"
$ _SESSION仍为空:( 任何想法?谢谢你的帮助
答案 0 :(得分:0)
会话ID默认存储在cookie中,因此不能在不同的域之间共享。我不确定是否将其设置为在网址中传播会产生影响
答案 1 :(得分:0)
来自suhosin的问题似乎是使用包含子域文档根的密钥对会话进行编码的问题。 suhosin.session.cryptdocroot 设置。
http://rommelsantor.com/clog/2011/02/06/php-shared-session-encoding-solution/