新しいウィンドウ/タブの新しいセッションを開くための重要な解決策が見つからなかったので、うまくいくように見える次の解決策を考えました:
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
([SubSession->]$SESSIONSTORE
配列内の)配列の n 個のコピーをシリアル化し、配列がシリアル化され、別の方法を使用してシリアル化解除さ
れることを知っているので、 それらをシリアル化解除するといくつかの問題が発生する可能性がありますか?$_SESSION
- php が
__destruct()
スクリプトの最後でメソッドを呼び出す順序
については言わないので、このクラスが最後に破棄されることをどのように確認できますか?
(これにより、サブセッション² がアクティブなときに、他の自己シリアル化¹ が 'MAIN' $_SESSION に保存されるのを防ぐことができます。
[SubSession->]$SESSIONSTORE
1: 自己シリアリングという言葉を使用して、破棄される前に$_SESSION 配列のどこかで自分自身をシリアライズするクラスを意味し$__SUB_SESSION->forkActive($subSessID);
ます$__SUB_SESSION->activate($subSessID);