【问题标题】:PHP Multiple Concurrent Sessions Per User每个用户的 PHP 多个并发会话
【发布时间】:2011-08-29 08:22:34
【问题描述】:

我正在开发一个在 Apache 上使用 PHP 的网络应用程序。 $_SESSION 变量用于必须跨页面持久的信息。

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

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

【问题讨论】:

  • 不可能。您需要编写自己的会话处理脚本,并将 if through 附加到每个 URL。
  • pass if through appended to every URL 可能出了什么问题?

标签: php session-variables multiple-instances


【解决方案1】:

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

作为开发人员,我通常需要同时测试不同用户类型(Administrator、Registered、Visitor 等)的界面。 Firefox 浏览器有一个“多帐户容器”附加组件,除其他外,它使 cookie 按容器分隔。可以根据需要创建尽可能多的容器,并在每个容器中打开选项卡。每组包含的选项卡共享 cookie,但不跨容器共享。浏览器将使用不同的独立“PHPSESSID”(或者您命名的 cookie),因此能够同时处理多个会话。

还有其他扩展和注意事项,例如特殊书签等,但它们超出了这里的问题范围。

【讨论】:

    【解决方案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>";
    

    【讨论】:

      【解决方案3】:

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

      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(){}
      }
      }
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我们有这个需求的原因是由于应用程序的使用方式。例如销售人员可能需要在任何给定时间打开多个订单输入屏幕。这可能是因为出于各种原因需要将一个客户临时移交给另一位工作人员。然后,销售人员需要能够为队列中的下一个人开始新订单,而不会干扰已经打开的订单,这将在原始客户被交还时完成。对于旧系统,这是通过打开应用程序的多个副本(不是基于 Web)来完成的。
        • 啊,我明白了。 :) 您可以更改站点的工作方式,以便在会话中不保留销售人员的当前订单。相反,您可以使用更 RESTful 的方法 [xml.com/pub/a/2004/08/11/rest.html],其中销售人员正在更新的订单 ID 是网页 URL 的一部分。这样,他们可以打开两个选项卡/窗口并修改两个订单,会话将完全消失。
        • 接受上述评论的答案,而不是答案本身。
        【解决方案5】:

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

        会话不必担心它们在哪个选项卡中。

        另外,如果选项卡 1 中的会话 1 打开一个新窗口会怎样?这是一个新的会话吗?

        【讨论】:

        • 这是我能找到的关于此事的最佳文章:php.net/manual/en/ref.session.php#74557
        • @onteria_ 这似乎为滥用做好了准备:So, every link, form, header() and Javascript code will forward the SESSION_NAME value to the next script and it will know which is the session it must use.
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-24
        • 1970-01-01
        • 2013-03-13
        • 1970-01-01
        • 2015-01-01
        • 1970-01-01
        • 2014-02-18
        相关资源
        最近更新 更多