PHP-每个选项卡的会话数
是否可以按浏览器选项卡创建会话 例如,用户在其浏览器中打开了两个选项卡: 表1和表2 在选项卡1中他有一个会话:PHP-每个选项卡的会话数,php,session,tabs,Php,Session,Tabs,是否可以按浏览器选项卡创建会话 例如,用户在其浏览器中打开了两个选项卡: 表1和表2 在选项卡1中他有一个会话: $_SESSION['xxx'] = 'lorem'; 在选项卡2中,会话是: $_SESSION['xxx'] = 'ipsum'; 现在刷新时,我需要在活动选项卡中获取当前会话。例如,如果用户刷新选项卡2,我需要获取加载的选项卡2的$\u会话['xxx'],即“ipsum”。但是$\u会话['xxx']不应在选项卡1上更改 是否有任何选项可以保存每个选项卡的会话。如果没有,还
$_SESSION['xxx'] = 'lorem';
在选项卡2中,会话是:
$_SESSION['xxx'] = 'ipsum';
现在刷新时,我需要在活动选项卡中获取当前会话。例如,如果用户刷新选项卡2,我需要获取加载的选项卡2的$\u会话['xxx']
,即“ipsum”。但是$\u会话['xxx']
不应在选项卡1上更改
是否有任何选项可以保存每个选项卡的会话。如果没有,还有什么其他选择来处理这个问题
谢谢你的帮助 PHP将会话ID存储在cookie中,cookie是针对每个客户端(浏览器),而不是选项卡。因此,没有简单易行的方法可以做到这一点。可以通过创建自己的会话处理程序来实现这一点,但它们更多的是黑客,而不是解决方案,因此具有自身的风险和复杂性。无论出于何种原因,您可能需要它,我确信有一种比会话拆分更好的体系结构解决方案。我一直在网上搜寻这个问题的答案,但还没有找到令人满意的解决方案。我终于在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;
});
HTML5sessionStorage
不在选项卡之间共享,因此我们可以在那里存储唯一的选项卡ID。在窗口上监听beforeunload
事件会告诉我们要离开(并加载其他页面)。通过在离开前设置cookie,我们可以在新请求中包含我们的值,而无需任何额外的URL操作。要区分选项卡,只需在服务器上选中$\u COOKIE['tab\u id']
,并适当存储会话值
请注意,Firefox的行为很奇怪,因为触发窗口。open()
将创建一个与其父级共享会话存储的窗口,为您提供两个具有相同ID的选项卡。手动打开空白选项卡,然后导航到目标URL将为您提供单独的存储空间。到目前为止,Chrome在我所有的测试中都适用
我意识到这可能不是正确的答案,甚至不是一个“好”的答案,但这是一个答案。我一直在尝试使用此功能制作一个web应用程序
它还没有成熟,并且有约束和流,比如如果您的javascript根据它向外部php代码发送帖子,就必须在url中传输会话id,但它是功能性的,适合我的需要(目前)
我正在考虑一个更安全的解决方案,所以请根据您的需要调整它,并给我您的建议
<?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;
}
};
?>
这是我的解决方案;我们使用它来允许每个客户端打开多个应用程序视图
发布以获取数据:
“doStuff=getData&model=GTD&sn=6789&type=random&date=2018年12月18日”
然后,控制器从表中获取数据,为设备构建对象,将其存储到会话对象,并将其存储在变量中。它生成每个选项卡的guid,以便用户可以将同一仪器与UI中的不同视图进行比较
$\会话[$model][$sn][$type][$guid][$key]
当然,guid也会发送回数据对象,以便选项卡知道以后如何调用该数据
当用户想要将结果打印到文件(pdf等)时,它会发送一篇文章,其中包含文章中的相关数据
'doStuff=saveFile&model=GTD&sn=6789&type=random&calDate=2018年12月18日&guid=randomKey'
然后,控制器将其传递到存储器以进行检索
会话类文件示例:
<?php
class Session {
public $fieldKey1;
public $fieldKey2;
public function GetStorage($model, $sn, $type, $guid, $key) {
return $_SESSION[$model][$sn][$type][$guid][$key];
}
}
?>
控制器文件:
<?php
require_once('session.php');
global $session; //from session class file
switch($_POST['doStuff']) {
case 'saveFile':
$session->GetStorage($_POST['model'], $_POST['sn'], $_POST['type'], $_POST['guid'], $key);
break;
}
?>
这允许用户拥有相同数据的多个视图,而无需覆盖每个选项卡中的数据集。如果每个选项卡不需要那么多的数据粒度,当然可以简化$\u会话变量的键数。按选项卡,您指的是浏览器选项卡,对吗?这非常类似于这个问题:您可以在那里找到答案。我面临这个问题,我使用类似于$\u会话['xxx']['uniquevalue']
,但我的运气是我用它来处理提交表单,所以我可以添加一个具有唯一值的唯一隐藏字段。。。。duno我的方法是否可以接受,但是否有效……)是的,我用url参数做的:)谢谢你的回答@Auris,当您打开多个窗口时,这是一个很好的用途。一个有新闻,另一个有Facebook,第三个有需要登录的出色应用程序。使用普通会话cookie,您可以登录,然后关闭该选项卡/窗口。但由于其他选项卡/窗口仍处于打开状态,因此会话仍处于活动状态。您可以重新打开新的选项卡/窗口,无需登录。我认为当应用程序窗口关闭时,会话终止,从而强制重新登录会更好。对于普通会话cookie,会话直到所有窗口都关闭后才会终止。@UncaAlby Hi,会话实际上在关闭窗口时终止,只要在cookie未过期的情况下再次打开时使用cookie中存储的id重新生成会话即可。然而,这不是问题的重点。Ihuber希望在不同的选项卡中为同一实体设置两个单独的会话。这是clinet功能,在服务器端并没有“干净”的方法来实现这一点。在您的示例中,您使用了3个不同的应用程序。这些应用程序有自己的会话实体,彼此无法访问(例如,您的超级应用程序无法管理FB会话容器-web security 101中的变量)。是的,这可能会起作用,但同样,这是一种黑客行为。如果你正在构建一些个人的东西并使用它,这是很好的,但是如果你正在构建一个propper商业产品,并且有人审查了你的代码,那么你很可能会因此而被解雇。您正在将基于应用程序的会话存储在选项卡id下,这意味着在公用计算机上,打开该选项卡id的任何人都可以使用您的会话。此外,如果用户以不同的选项卡顺序加载具有不同会话的应用程序组件,该怎么办就像我说的,这很好