PHP:在新会话中打开一个新窗口(解决方案正确吗?)

时间:2013-11-23 18:56:57

标签: php serialization session-variables session-state new-window

由于我没有找到任何重要的解决方案来打开新窗口/标签的新会话,我想到了以下似乎有效的解决方案:

1-创建了一个类似单例类'SubSession'

<?php

/**
 * Provides a data structure and routines to be able to create and/or
 * activate a subSession
 * @author Roberto CASULA (casual4free@gmail.com)
 */
final class SubSession {
   private static $instance = NULL;

   private $current_active_name = 'MAIN';
   private $SESSIONSTORE = array();

   private $MAIN_SESSION;

   private function currentSessionStore() {
      $active_name = $this->current_active_name;
      $this->SESSIONSTORE[$active_name] = $_SESSION;
   }
   private function mainSessionStore() {
      $active_name = $this->current_active_name;
      if($active_name !== 'MAIN')
         throw new BadMethodCallException(__CLASS__.': the current active subSession is not MAIN');
      $this->MAIN_SESSION = $_SESSION;
   }

   public function exists($name) {
      return array_key_exists($name, $this->SESSIONSTORE);
   }

   public function forkActive($name) {

      if( $this->exists($name) )
         throw new InvalidArgumentException(__CLASS__.": $name yet exists");

      $this->SESSIONSTORE[$name] = $_SESSION;
   }

   public function activate($name) {
      $active_name = $this->current_active_name;

      if($name === $active_name) return 'yet_active';

      if($name == 'MAIN') :
         $this->currentSessionStore();
         $_SESSION = $this->MAIN_SESSION;
         $this->current_active_name = $name;
         return TRUE;

      elseif( $this->exists($name) ) :
         $this->mainSessionStore();
         $_SESSION = $this->SESSIONSTORE[$name];
         $this->current_active_name = $name;
         return TRUE;

      else :
         throw new InvalidArgumentException('The searched name do not exists: '.$name);

      endif;
   }

   public function __get($name) {
      switch ($name) {
         case 'MAIN_SESSION' :
            if($this->current_active_name === 'MAIN')
               return $_SESSION;
         default :
            return $$name;
      }
   }

   private function __construct() {}

   public function __wakeup() {}

   public function __sleep() {
      return array('SESSIONSTORE');
   }

   public function __destruct() {
      $this->activate('MAIN');
      $_SESSION[__CLASS__] = serialize($this);
   }
   /**
    * 
    * @return SubSession
    */
   public static function getInstance() {

      if( self::$instance !== NULL) :
         return self::$instance;

      elseif( isset($_SESSION[__CLASS__]) ) :
         return self::$instance = unserialize($_SESSION[__CLASS__]);

      else :
         return self::$instance = new self();

      endif;      
   }

}

2-在“session_start();”

之后添加了以下行
$__SUB_SESSION = SubSession::getInstance();

if( isset($_GET['sub_session_id']) ) {
   $subSessID = $_GET['sub_session_id'];

   if( !$__SUB_SESSION->exists($subSessID) )
      $__SUB_SESSION->forkActive($subSessID);

   $__SUB_SESSION->activate($subSessID);
}

3-在.htaccess中创建了一个条目

RewriteRule ^@sub_session_id=([^/]+)(.*)$ $2?sub_session_id=$1 [QSA]

现在:

  1. 因为我要序列化$_SESSION数组的n个副本(在[SubSession->]$SESSIONSTORE数组中)和
    知道$_SESSION数组是使用不同的方法序列化和反序列化的,
    当我反序列化时可能会出现一些问题?

  2. 因为我不知道php在脚本末尾以什么顺序调用__destruct()方法,我怎么能确定这个类最后会被销毁?
    (当subsession²处于活动状态时,这可以防止其他一些自序列化¹将存储在'MAIN'$ _SESSION上。

1:我使用self-serialing这个词来表示一个在被毁坏之前在$ _SESSION数组中的某个地方序列化的类 2:我打算通过[SubSession->]$SESSIONSTORE$__SUB_SESSION->forkActive($subSessID);创建并由$__SUB_SESSION->activate($subSessID);

激活的{{1}}位置复制$ _SESSION数组。

0 个答案:

没有答案