PHP – сеанс за вкладку

Можно ли делать сеансы на вкладках браузера?

В качестве примера пользователь открыл 2 вкладки в своем браузере: вкладка 1 и вкладка 2

В Tab 1 у него есть сеанс:

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

А в Tab 2 сеанс:

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

Теперь при обновлении мне нужно получить текущий сеанс на активной вкладке. Например, если пользователь обновляет вкладку 2, мне нужно получить $_SESSION['xxx'] для вкладки 2 при загрузке, которая является «ipsum». Но $_SESSION['xxx'] не следует изменять на вкладке 1.

Есть ли возможность сохранять сеансы на каждую вкладку. Если нет других вариантов решения этой проблемы?

Спасибо за любую помощь!

PHP хранит идентификаторы сеансов в куки-файлах и куки-файлы для каждого клиента (браузер), а не вкладки. Таким образом, нет простого и простого способа сделать это. Есть способы сделать это, создав свои собственные обработчики сеансов, но они больше хаки, чем решения, и, как таковые, имеют свои собственные риски и сложность. По какой-то причине вам может понадобиться это, я совершенно уверен, что есть лучшее архитектурное решение, чем сеансное расщепление.

Я искал Интернет для ответов на эту проблему и еще не нашел удовлетворительного решения. Я, наконец, собрал что-то в 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 не используется между вкладками, поэтому мы можем хранить там уникальный идентификатор табуляции. Прослушивание события beforeunload в окне говорит нам, что мы уходим (и загружаем другую страницу). Установив файл cookie, прежде чем мы уйдем, мы добавим наше значение в новый запрос без дополнительной обработки URL-адресов. Чтобы различать вкладки, вам просто нужно проверить $_COOKIE['tab_id'] на сервере и правильно сохранить значения сеансов.

Обратите внимание, что Firefox ведет себя странно, в этом запуске window.open() создаст окно, которое разделяет sessionStorage со своим родителем, давая вам две вкладки с тем же идентификатором. Ручное открытие пустой вкладки, а затем переход на целевой URL даст вам отдельное хранилище. Chrome работает для меня во всех моих тестах.

Я понимаю, что это, вероятно, неправильный ответ или даже «хороший» ответ, но это ответ.

Я сделал попытку сделать веб-приложение с этой функцией.

Он не был созрел и имеет ограничения и потоки, например, необходимость передавать идентификатор сеанса в URL-адресе, если ваш javascript делает запись на внешний php-код в зависимости от него, но он функциональный и соответствует моим потребностям (на данный момент).

Я думаю о более безопасном решении, поэтому не стесняйтесь приспосабливать его к вашим потребностям и давать мне свои предложения.

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

Используя пользователей Chrome, каждый пользователь Chrome имеет отдельный файл cookie и другой запрос сеанса.
Вы можете добавить пользователя столько, сколько хотите.