【问题标题】:How do you store non-serializable, process-specific objects between PHP requests?如何在 PHP 请求之间存储不可序列化的、特定于进程的对象?
【发布时间】:2017-09-08 22:52:04
【问题描述】:

我们需要保留一组与不同客户端浏览器会话相关联的套接字对象,以便当客户端的浏览器发出后续请求时,我们可以使用现有的套接字连接/会话在其上发出请求代表。套接字是不是 HTTP 的东西。有没有一种方法可以在 PHP 中存储这样的对象,并且可以跨页面请求生存?

【问题讨论】:

  • 这看起来与Is there a way to share object between PHP pages? 基本相同的问题,在相关问题列表的顶部。
  • 感谢指点!可悲的是,看起来答案是否定的。
  • 这些是域套接字吗?因为如果它们是本地套接字,您可以在磁盘上打开它们并将套接字路径存储在会话变量中以便在请求之间共享。
  • @MattS 它们是本地套接字。有趣的想法。我试试看。

标签: php sockets web


【解决方案1】:

在页面加载后,php 脚本会死掉,所以没有办法做到这一点。但是,您可以创建一个长期存在的守护进程,它将打开进程套接字所需的所有内容,并在页面重新加载之间保持打开状态。当然,您需要通过某种访问密钥来隔离这些套接字,以确保不同的会话无法访问其他用户的套接字。您还需要记住,它会在某个时刻死掉,因此请确保您有逻辑重新启动所有打开的套接字。但是肯定可以实现的。

谢谢。

【讨论】:

    【解决方案2】:

    这不是一个完整的答案;但它朝着答案迈出了一步。

    正如在其他地方指出的那样,ad nauseum,通过 Web 服务器(Apache、Nginx 等)使用 PHP 的标准经典模型不允许您这样做,因为每个页面hit 从一组全新的变量开始。

    三个想法:

    1. 您需要一个持久层。显然,这是您在数据库中存储内容的地方,或者使用APC(PHP7+ 中为APCu)、Redis 或类似的东西。

    但是,您的问题是您指定了“不可序列化”。

    1. 我的下一个建议是,也许您可​​以保留构造对象所需的元素,并为每个 PHP 请求重新初始化对象。它不会像您希望的那样具有惊人的性能,但它是最有用的解决方案,无需重写所有内容。也许你已经尝试过了。

    2. 下一步是完全在外面做一些事情。 NodeJS 基础架构的优势之一是整个服务器循环持续存在。

    因此,您可以尝试运行 PHP 的其他方法之一,例如 ReactPHPPHP FastCGI。 (还有其他的,但我想不起来了。如果我记得,我会编辑这个。)

    这涉及到一种完全不同的 PHP 编写方式——就像 NodeJS 编程与在浏览器中使用 jQuery 一样。它不会在 Apache 中运行。相反,它将作为应用程序直接在您的 Unix 服务器上运行。而且您必须满足诸如垃圾收集之类的问题,这样您就不会出现内存泄漏,并编写良好的紧密事件循环。

    有利的一面是,因为您的线程会持续存在并处理每个后续请求,所以您能够以您所追求的方式处理请求。

    【讨论】:

      【解决方案3】:

      您的评论提到这些是本地套接字。听起来 PHP 应用程序充当了套接字客户端。因此,PHP 会话唯一需要的是一个通用标识符,例如用户 ID,以及要一致命名的套接字。

      所以,例如:

      <?php 
      $userid = $_SESSION['userid'];
      $fp = stream_socket_client("unix:///tmp/socket-" . $userid, $errno, $errstr, 30);
      if ($fp) {
          fread...
      }
      

      【讨论】:

        【解决方案4】:

        有没有办法在 PHP 中存储这样的对象,这样可以跨页面请求保留下来?

        没有。

        zombat's answer 引用到very similar question

        在 PHP 中,没有页面实例的概念。对 Web 服务器的每个请求都是一个新的开始。所有的类都是重新加载的,所以没有类共享的概念,也没有资源池的概念,除非在外部实现。因此,在 Web 请求之间共享套接字实际上是不可能的。

        如果对象是可序列化的,您可以将 PHP 的 serialize()unserialize() 与 MySQL 内存表结合使用来解决此问题。除此之外,我认为您无能为力。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-24
          • 1970-01-01
          • 2013-05-12
          • 2010-12-28
          • 2012-07-31
          • 2015-02-14
          相关资源
          最近更新 更多