PHP每个用户多个并发会话

时间:2011-05-20 02:56:14

标签: php session-variables multiple-instances

我正在使用Apache上的PHP开发Web应用程序。 $ _SESSION变量对于必须在页面中保持不变的信息使用相当多。

我们需要每个用户能够打开多个并发会话,可以是新选项卡,也可以是新窗口,具体取决于他们选择的浏览器。现在,当用户打开添加选项卡或窗口并转到站点时,将采用现有会话。如何防止这种情况,以便用户必须(或可能)登录并开始新会话,而不会干扰他们已经打开的任何现有会话?

我们的临时解决方法是使用多个浏览器(IE和FF),但这显然不是一种非常理想的做事方式。

5 个答案:

答案 0 :(得分:8)

您描述的行为反对浏览器会话的概念。为什么用户想要多个会话?是否需要强制执行用户访问控制?如果是,请将用户分配给逻辑组并向特定组授予权限。用户是否需要代表其他用户执行某些操作?如果是这样,请围绕该概念设计网站,而不是尝试为单个用户创建多个会话。

如果你真的必须这样做,你可以做一些可怕的事情,比如在页面之间传递查询参数(非常不安全!)作为会话ID,完全绕过实际的$ _SESSION并且管理自己的会话概念。同样,这不正常,将来只会导致头痛/安全问题。

答案 1 :(得分:2)

可以使用以下伪编码逻辑模拟非原子并发会话管理访问:

function main(){
  $locker = new SessionLocking();
  /** read elements the $_SESSION "cached" copy. **/
  $var1 = $_SESSION['var1'];
  $var2 = $_SESSION['var2'];
  /** Pseudo Atomic Read **/
  $locker->lock(); //session is locked against concurrent access.
  $var3 = $_SESSION['var3'];
  $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script.
  /** Psuedo Atomic Write **/
  $locker->lock(); //session is locked against concurrent access.
  $_SESSION['var4'] = "Some new value";
  $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script
}

CLASS SessionLocking {

private static $lockCounter=0;
private static $isLoaded=false;

function __constructor(){
  if (!self::$isLoaded) load();
}

private function load(){
 $this->lock();
 $this->unlock();
}

private function lock(){
  if ($lockCounter<1) try {session_start();} Catch(){}
  $lockCounter++; 
}

private function unlock(){
  if ($lockCount<1) return;
  $lockCounter--;
  if ($lockCounter<1) try {session_write_close();} Catch(){}
}
}

答案 2 :(得分:1)

如果可能的话,这将很难做到。

会话不应该担心他们所处的标签。

此外,如果标签1中的会话1打开一个新窗口会发生什么?这是新会议吗?

答案 3 :(得分:0)

知道这是一个很晚的答案...

作为开发人员,我通常需要同时测试不同用户类型(管理员,注册用户,访问者等)的界面。 Firefox浏览器具有一个“多帐户容器”附加组件,除其他功能外,它还使cookie按容器分开。可以创建所需数量的容器,并在每个容器中打开选项卡。每套包含的选项卡共享cookie,但不能跨容器共享。浏览器将使用不同的独立“ PHPSESSID”(或者您将其命名为Cookie),从而能够处理多个同时进行的会话。

还有其他扩展名和注意事项,例如特殊书签等,但它们不在此处的讨论范围内。

答案 4 :(得分:-2)

这是一种方法:

- 首先在php.ini中禁用会话cookie:

session.use_cookies = 0

这可以确保不会使用cookie来传递会话ID。

- 然后确保生成包含会话ID的所有URL(通过函数session_id()获取它,例如:

print "<a href= \"http://www.example.com/".session_id()."&showlist=1\">show list</a>";