2016-01-15 16 views
6

Ist es möglich, Sitzungen pro Browser Tabs zu machen?PHP - Sitzung pro Registerkarte

Als Beispiel eröffnet ein Benutzer 2 Tabs in seinem Browser: Tab 1 und Tab 2

In Tab 1 er hat eine Sitzung:

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

Und in Tab 2 Die Sitzung ist:

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

Jetzt auf Aktualisieren muss ich die aktuelle Sitzung in der aktiven Registerkarte abrufen. Zum Beispiel, wenn der Benutzer Tab 2 aktualisiert, muss ich die $_SESSION['xxx'] für Registerkarte 2 auf laden, die "ipsum" ist. Aber $_SESSION['xxx'] sollte nicht auf Registerkarte 1 ändern.

Gibt es eine Option zum Speichern von Sitzungen pro Registerkarte. Wenn nicht, was sind andere Optionen, um mit diesem Problem umzugehen?

Danke für jede Hilfe!

+0

Mit Registerkarte, meinen Sie Browser-Registerkarte, richtig? – vitozev

+0

@vitozev yeah :) – lhuber

+0

Dies ist dieser Frage sehr ähnlich: http://stackoverflow.com/questions/6067009/php-multiple-concurrent-sessions-per-user Sie können Ihre Antwort dort finden. –

Antwort

9

PHP speichert Session-IDs in Cookies und Cookies sind pro Client (Browser), nicht tab. Es gibt also keinen einfachen und einfachen Weg dies zu tun. Es gibt Wege, dies zu tun, indem Sie Ihre eigenen Session-Handler erstellen, aber sie sind mehr Hacks als Lösungen und daher mit ihren eigenen Risiken und Komplexität. Aus welchen Gründen auch immer Sie dies benötigen, ich bin mir ziemlich sicher, dass es eine bessere architektonische Lösung als das Teilen von Sitzungen gibt.

+1

yep ich habe es mit URL-Parametern gemacht :) danke für deine Antwort! – lhuber

+0

@Auris, eine sehr gute Verwendung für diese ist, wenn Sie mehrere Fenster geöffnet haben. Einer hat die News auf, ein anderer hat Facebook, und der dritte hat Ihre Magnificent Application, die eine Anmeldung erfordert. Mit normalen Sitzungscookies können Sie sich anmelden und dann das Tab/Fenster schließen. Da jedoch die anderen Registerkarten/Fenster noch geöffnet sind, bleibt die Sitzung aktiv. Sie können ein neues Tab/Fenster erneut öffnen und müssen sich nicht anmelden. Ich denke, es wäre besser, wenn die Anwendung beim Schließen des Anwendungsfensters abstirbt und somit eine neue Anmeldung erzwingt. Bei normalen Sitzungscookies stirbt die Sitzung erst, wenn alle Fenster geschlossen sind. – UncaAlby

+0

@UncaAlby Hallo, Session stirbt tatsächlich, wenn Sie das Fenster schließen, es wird einfach mit der im Cookie gespeicherten ID neu erstellt, sobald Sie es erneut öffnen, wenn der Cookie nicht abgelaufen ist. Aber das ist nicht der Punkt der Frage. Ihuber wollte 2 separate Sitzungen für die gleiche Entität in verschiedenen Tabs haben. Dies ist die Clinet-Funktionalität und es gibt keine "saubere" Möglichkeit, dies auf der Serverseite zu tun. In Ihrem Beispiel haben Sie 3 verschiedene Apps verwendet. Diese Apps haben ihre eigenen Sitzungsentitäten, die keinen Zugriff aufeinander haben (z. B. kann Ihre Super-App keine Variablen im FB-Sitzungscontainer verwalten - Websicherheit 101). – Auris

4

Ich habe das Web nach Antworten auf dieses Problem durchforstet und habe noch keine befriedigende Lösung gefunden. Ich habe schließlich in JavaScript diese Art von Arbeiten zusammengezogen.

//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 nicht zwischen den Tabs geteilt, so dass wir dort eine einzigartige Registerkarte ID speichern. Das Hören auf das beforeunload Ereignis im Fenster sagt uns, dass wir gehen (und eine andere Seite laden). Indem wir ein Cookie setzen, bevor wir es verlassen, fügen wir unseren Wert in die neue Anfrage ohne zusätzliche URL-Manipulation ein. Um zwischen den Registerkarten zu unterscheiden, müssen Sie nur $_COOKIE['tab_id'] auf dem Server überprüfen und die Sitzungswerte entsprechend speichern.

Beachten Sie, dass sich Firefox merkwürdig verhält, indem das Triggern window.open() ein Fenster erstellt, das mit seinem übergeordneten Element teilt und Ihnen zwei Registerkarten mit derselben ID gibt. Wenn Sie manuell eine leere Registerkarte öffnen und dann zur Ziel-URL navigieren, erhalten Sie einen separaten Speicher. Chrome funktioniert für mich in allen meinen bisherigen Tests.

Ich realisiere, das ist wahrscheinlich nicht die richtige Antwort oder sogar eine "gute" Antwort, aber es ist eine Antwort.

+0

Ja, das mag funktionieren, aber nochmal, das ist ein Hack. Wenn Sie etwas Persönliches bauen und das verwenden, ist es in Ordnung, aber wenn Sie ein kommerzielles Produkt erstellen und jemand Ihren Code überprüft, werden Sie höchstwahrscheinlich einfach dafür gefeuert. Sie speichern App-basierte Sitzungen unter der Tab-ID, dh auf einem öffentlichen Computer sind Ihre Sitzungen für jeden verfügbar, der diese Tab-ID öffnet. Was passiert auch, wenn Benutzer App-Komponenten mit unterschiedlichen Sitzungen in einer anderen Tab-Reihenfolge laden? - Wie ich schon sagte, das ist gut zum Spielen, aber kann nicht in einer besseren Lösung verwendet werden. – Auris

+0

Ich denke, Ihre Kritik ist ein wenig unfair, da dies der Beginn einer angemessenen Lösung ist: Anstatt die Sitzungs-ID vom Cookie an die Website zu übergeben, würden Sie eine Tab-ID + Sitzungs-ID vom Cookie an die Website übergeben. – frankster

0

Ich habe eine Aufnahme gemacht, um eine Web-App mit dieser Funktion zu erstellen.

Es wurde nicht gereift und haben Einschränkungen und fließt, wie die Session-ID in der URL zu übertragen, wenn Ihr Javascript einen Beitrag zu einem externen PHP-Code abhängig machen, aber es ist funktional und meinen Bedürfnissen (vorerst).

Ich denke an eine sicherere Lösung, also zögern Sie nicht, es an Ihre Bedürfnisse anzupassen und geben Sie mir Ihre Vorschläge.

<?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; 
    } 
}; 
?>