2016-01-15 40 views
6

ブラウザごとのセッションタブを作成できますか?PHP - セッションごとのタブ

ユーザがブラウザに2つのタブを開いた例として: タブ1タブ2

タブでは1彼はセッションを持っています

$_SESSION['xxx'] = 'lorem'; 

そしてタブで2セッションは次のとおりです。

$_SESSION['xxx'] = 'ipsum'; 

今更新するには、アクティブなタブで現在のセッションを取得する必要があります。例えば、ユーザーがTab 2をリフレッシュする場合、「ipsum」のロード時にタブ2に対して$_SESSION['xxx']を取得する必要があります。しかし、$_SESSION['xxx']はタブ1で変更しないでください。

タブごとにセッションを保存するオプションはありますか?この問題を処理するその他のオプションは何ですか?

ありがとうございました!

+0

タブでは、ブラウザタブを意味します。 – vitozev

+0

@vitozev yeah :) – lhuber

+0

これはこの質問に非常によく似ています:http://stackoverflow.com/questions/6067009/php-multiple-concurrent-sessions-per-userそこに答えがあります。 –

答えて

9

PHPはセッションIDをCookieに保存し、Cookieはクライアント(ブラウザ)ごとにタブではなく保存します。したがって、これを行う簡単で簡単な方法はありません。独自のセッションハンドラを作成することでこれを行う方法がありますが、ソリューションよりもハッキングされているため、リスクや複雑さが伴います。あなたがこれを必要とするかもしれない何らかの理由で、セッション分割よりも優れたアーキテクチャ上の解決策があると確信しています。

+1

うん、私はURLパラメータでそれを作った:)あなたの答えに感謝! – lhuber

+0

@Auris、これは、複数のウィンドウが開いているときに非常に便利です。 1つはニュースがあり、もう1つはFacebookがあり、3つ目はログインが必要なMagnificent Applicationがあります。通常のセッションCookieを使用すると、ログインしてそのタブ/ウィンドウを閉じることができます。しかし、他のタブ/ウィンドウはまだ開いているので、セッションはAliveのままです。新しいタブ/ウィンドウを再度開くことができ、ログインする必要はありません。私は、アプリケーションウィンドウが閉じたときにセッションが終了し、新しいログインを強制する方が良いと思う。通常のセッションCookieでは、すべてのウィンドウが閉じられるまでセッションは終了しません。 – UncaAlby

+0

@UncaAlbyこんにちは、セッションは、ウィンドウを閉じたときに実際には消えます。クッキーが期限切れになっていない場合は、再度開きます。しかし、それは問題のポイントではありません。 Ihuberは、同じエンティティに対して2つの別々のセッションを別々のタブに入れたいと思っていました。これは臨床的機能であり、サーバー側でこれを行うための「クリーン」な方法はありません。あなたの例では、3つの異なるアプリを使いました。これらのアプリには、互いにアクセス権のない独自のセッションエンティティがあります(たとえば、スーパーアプリケーションはFBセッションコンテナ内の変数 - ウェブセキュリティ101を管理できません)。 – Auris

4

私はこの問題に対する答えをウェブで精査してきましたが、まだ満足のいく解決策を見つけていません。私は最終的にJavaScriptの何かを一緒に引っ張って、そのような仕事をしました。

//generate a random ID, doesn't really matter how  
if(!sessionStorage.tab) { 
    var max = 99999999; 
    var min = 10000000; 
    sessionStorage.tab = Math.floor(Math.random() * (max - min + 1) + min); 
} 

//set tab_id cookie before leaving page 
window.addEventListener('beforeunload', function() { 
    document.cookie = 'tab_id=' + sessionStorage.tab; 
}); 

HTML5 sessionStorageは、タブ間で共有されていないので、私たちはそこに固有のタブIDを保存することができます。ウィンドウのbeforeunloadイベントをリッスンすると、私たちは退室していることがわかります(そして、他のページをロードしています)。私たちが退室する前にクッキーを設定することにより、特別なURL操作をせずに新しいリクエストに値を含めることができます。タブを区別するためには、サーバー上で$_COOKIE['tab_id']をチェックし、セッション値を適切に保存するだけです。

Firefoxがその引き金window.open()で、動作がおかしいことに注意してくださいは、あなたに同じIDを持つ2つのタブを与え、その親とのsessionStorageを共有するウィンドウを作成します。空白のタブを手動で開き、ターゲットURLに移動すると、別々のストレージが提供されます。これまでのすべてのテストでChromeは私のために働いています。

私はこれが正しい答えではない、または「良い」回答でもあることを認識していますが、と答えはです。

+0

はい、これはうまくいくかもしれませんが、これもまたハックです。個人的なものを構築してこれを使っているのであれば問題ありませんが、プロッパーの商用製品を構築していて誰かがあなたのコードを見直しているのであれば、おそらくこれで解雇されるでしょう。あなたは、タブIDの下にアプリケーションベースのセッションを保存しています。つまり、公開されているコンピュータでは、そのタブIDを開いている誰でもセッションを利用できます。また、ユーザーが別のセッションで異なるタブ順でアプリコンポーネントを読み込むとどうなりますか? - 私が言ったように、これは遊びには良いですが、プロッパーソリューションでは使用できません。 – Auris

+0

あなたの批判はちょっと不公平だと思います。セッションIDをクッキーからウェブサイトに渡すのではなく、クッキーからウェブサイトにタブID +セッションIDを渡します。 – frankster

0

私はこの機能を使ってWebアプリケーションを作成しています。

javascriptがそれに応じて外部PHPコードへの投稿を行う場合、セッションIDをURLに送信する必要があるように、成熟しておらず、制約とフローがありますが、機能的であり、 )。

私はより安全な解決策を考えていますので、自由にあなたのニーズに適応させて、私にあなたの提案をしてください。

<?php 
/** 
* Split $_SESSION by browser Tab emulator. 
* methods exemples are used whith : 
* $session = new SessionSplit(); 
* as SessionSplit may reload the page, it has to be used on top of the code. 
* 
*/ 
class SessionSplit{ 
    public $id; 
    private $gprefix="session_slice_"; 
    private $prefix=""; 
    private $witness=""; 
    function SessionSplit($witness='witness'){ 
     if(session_status()===PHP_SESSION_NONE){ 
      session_start(); 
     } 
     $this->witness=$witness; 
     if($this->get_id()){ 
      $this->prefix=$this->gprefix.$this->id; 
      //set a witness to 'register' the session id 
      $this->set($this->witness,'true'); 
     }else{ 
      // force the session id in the url to not interfere with form validation 
      $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; 
      $new_link = $actual_link.(strpos($actual_link,'?')===false?'?':'&'). 
       'session_id='.$this->id; 
      header('Location: '.$new_link); 
     } 
    } 
    private function get_id(){ 
     if(isset($_GET['session_id'])){ 
      $this->id=$_GET['session_id']; 
      return true; 
     }else{ 
      $this->new_id(); 
      return false; 
     } 
    } 
    private function new_id(){ 
     $id=0; 
     while(isset($_SESSION[$this->gprefix.$id.'.'.$this->witness])){$id++;} 
     $this->id=$id; 
    } 
    // ----------- publics 
    public function clearAll(){ 
     foreach($_SESSION as $key=>$value){ 
      if(strpos($key,$this->prefix.'.')===0){ 
       unset($_SESSION[$key]); 
      } 
     } 
    } 
    /** 
    * $is_user=$session->has('user'); 
    * equivalent to 
    * $is_user=isset($_SESSION['user']); 
    * @param {string} $local_id 
    * @return {boolean} 
    */ 
    public function has($local_id){ 
     return isset($_SESSION[$this->prefix.'.'.$local_id]); 
    } 
    /** 
    * 
    * $session->clear('user'); 
    * equivalent to 
    * unset($_SESSION['user']); 
    * @param {string} $local_id 
    */ 
    public function clear($local_id){ 
     unset($_SESSION[$this->prefix.'.'.$local_id]); 
    } 
    /** 
    * $user=$session->get('user'); 
    * equivalent to 
    * $user=$_SESSION['user']; 
    * @param {string} $local_id 
    * @return {mixed} 
    */ 
    public function get($local_id){ 
     if (isset($_SESSION[$this->prefix.'.'.$local_id])) { 
      return $_SESSION[$this->prefix.'.'.$local_id]; 
     }else return null; 
    } 
    /** 
    * $session->set('user',$user); 
    * equivalent to 
    * $_SESSION['user']=$user; 
    * @param {string} $local_id 
    * @param {mixed} $value 
    */ 
    public function set($local_id,$value){ 
     $_SESSION[$this->prefix.'.'.$local_id]=$value; 
    } 
}; 
?> 
関連する問題