由于我没有找到任何重要的解决方案来打开新窗口/标签的新会话,我想到了以下似乎有效的解决方案:
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]
现在:
$_SESSION
数组的n个副本(在[SubSession->]$SESSIONSTORE
数组中)和$_SESSION
数组是使用不同的方法序列化和反序列化的,__destruct()
方法,我怎么能确定这个类最后会被销毁?
1:我使用self-serialing这个词来表示一个在被毁坏之前在$ _SESSION数组中的某个地方序列化的类
2:我打算通过[SubSession->]$SESSIONSTORE
中$__SUB_SESSION->forkActive($subSessID);
创建并由$__SUB_SESSION->activate($subSessID);