如何在PHP请求之间存储不可序列化的特定于流程的对象?

时间:2017-04-13 00:31:09

标签: php sockets web

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

4 个答案:

答案 0 :(得分:4)

  

有没有办法在PHP中存储这样的对象,这些对象可以在页面请求中存活?

没有

引用zombat's answervery similar question

  

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

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

答案 1 :(得分:2)

这不是一个完整的答案;但它走向了答案。

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

三个想法:

  1. 您需要一个持久层。显然,这是您在数据库中存储内容的地方,或使用APC(PHP7 +中的APCu),Redis或类似内容。
  2. 但是,您的问题是您指定了#34; unserializable。"

    1. 我的下一个建议是,也许你可以坚持构造对象所需的元素,并为每个PHP请求重新初始化对象。它不会像你想的那样具有惊人的高效性,但它是最有用的解决方案而不必重写eveything。也许你已经尝试过了。

    2. 下一步是完全在那里做点什么。 NodeJS基础架构的优点之一是整个服务器循环仍然存在。

    3. 因此,您可以尝试运行PHP的其他方法之一,例如ReactPHPPHP FastCGI。 (还有其他人,但我无法忘记他们。如果我记得,我会编辑这个。)

      这涉及一种完全不同的编写PHP的方式 - 与NodeJS编程不同的是,在浏览器中填充jQuery。它不会在Apache中运行。相反,它将直接作为Unix服务器上的应用程序运行。而且你必须满足垃圾收集这样的事情,这样你就不会有内存泄漏,并编写好的紧密事件循环。

      优点是,因为您的主题会持续存在并处理每个后续请求,所以您能够完全按照您之后的方式处理请求。

答案 2 :(得分:2)

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

感谢。

答案 3 :(得分:-1)

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

所以,例如:

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