2012-07-25 155 views
0

我已經設置了會話以保存在數據庫中。我想跨多個子域共享同一會話,但似乎每個子域會覆蓋另一個子域的會話。PHP從mysql數據庫初始化會話數據時出錯

例如,我在一個子域的會話中添加了一些變量,它們在其上顯示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是一樣的。我確實在讀方法的var_dump,它似乎從數據庫中讀取OKY:

string(1484)"X3pJX1JQTk9LeW9fQVBBWk03dnhNMVFKNmxLZk1YdEtIMkNGS3EzdW5Oa0hvUFVaWTZJdHlyMzJUc09MUDUwUFpBZHZXTDZfbzM3SjhSbmp1T3lfVnBkMEdSY0dqQzc ......"

仍然是$ _SESSION是空的:( 對您有所幫助

+0

嘿,我有同樣的問題 - 你能解決這個問題嗎? – Dan 2012-12-25 14:05:31

回答

0

會話ID的任何ideeas感謝?默認情況下存儲在一個cookie中,所以不能在不同的域之間共享。我不知道是否將它設置爲在url中傳播會產生影響

+0

我正在跨子域共享會話 – 2012-07-25 07:21:23

+0

您是否嘗試通過網址傳播會話ID? – periklis 2012-07-25 07:53:48

+0

這不是獲得會話ID的問題,請閱讀整個問題 – 2012-07-25 07:56:04