【问题标题】:Storing objects between requests in PHP without serialising在 PHP 中的请求之间存储对象而不进行序列化
【发布时间】:2011-07-28 17:58:54
【问题描述】:

我正在用 PHP 编写一个有状态的 Web 应用程序,其中的状态可能包含很多对象。此时,我将所有这些对象保存在 $_SESSION 中,并在请求结束时将它们序列化。这有点痛苦,因为序列化整个会话需要几秒钟,而反序列化则需要更多时间。

我想尝试 APC,因为我希望这些对象只是被内存复制,而不是序列化。唉,似乎如果我提供apc_store($object) 一个对象,它似乎无论如何都会在将它传递给另一个进程之前对其进行序列化。 (故事是原始值和数组在没有序列化的情况下被内存复制,但这对我来说不是一个相关的解决方案,因为我的会话对象有很多(循环)引用。)

我的问题:有没有一种已知的方法可以在 PHP 中保持对象的持久性,而不必在每次请求后对它们进行序列化?我听说HipHop 解释器可以帮助解决这个问题,但我没有在网上找到任何工作示例。有人可以告诉我在 PHP 中是否可行?

(我知道,我应该用 Java 或其他支持无需 TCP 连接的持久实例的语言编写这个项目)

【问题讨论】:

  • 如果序列化你的 $_SESSION 需要几秒钟,你在 $_SESSION 中存储的太多了。使用适当的数据存储(如数据库),并仅存储/检索您需要的“会话”部分。
  • PHP 没有全局本地内存存储。如果您需要,您确实需要另一种语言(例如 Java)。或者按照建议清理您的会话。很有可能您可以通过在 __sleep 方法中删除循环引用(如果这是 PHP 有问题的话)来节省大量时间,而是在 __wakeup 上存储一种恢复它们的方法。
  • @AlienWebguy:也序列化字符串。
  • 在我的全状态 Web 应用程序中,我将大部分对象卸载到一个 xml 存储中,该存储也可以作为智能配置 xml。因此,我不需要序列化太多对象,而只需要序列化 ​​xml 文件的子集(状态)。这仍然是一种服务器端方法,但您可以尝试将序列化卸载到客户端?但也许你序列化了太多的对象?为什么不在运行时将对象存储在文件中?

标签: php serialization state persistent-storage


【解决方案1】:

每当您需要存储(冻结)对象时,都需要对其进行序列化。这与存储(APC、会话文件、数据库等)无关,这是因为脚本进程将终止,并且在下次启动时,对象需要再次活跃起来。

所以事情不能保持在“运行状态”,对象总是会被序列化来存储。

众所周知,PHP 序列化并不是最快的。它有其他实现,您可以使用,例如igbinary PHP extension。它在透明会话处理旁边提供了序列化/反序列化功能。也许这实际上对您的方案有帮助。

无论如何:在会话中存储的越多,在请求开始时需要解冻或唤醒的时间越多,所需的时间就越多。

相关:What is the php_binary serialization handler?

【讨论】:

  • 不正确,当 APC 在 mod_php 模式下运行时,会生成并持久存储所有 APC 数据的 Apache 进程。当一个 PHP 脚本终止时,它会将使用 apc_store 存储的数据复制到另一个进程,这使其可用于下一个请求。严格来说,这里不需要序列化,PHP 应该(理论上)能够 mem-copy 一个对象的内存。但出于某种原因,他们还是决定这样做。
  • @Pelle ten Cate:所以你的“不正确”论点只是 for 序列化的另一个事实例子?您能想象在 APC 中使用序列化的哪些原因?
  • 序列化为标准格式(例如 json)可能相对较慢,但对于使用var_export 序列化到另一个 PHP 文件的简单结构可能非常快。通过这种方式,它确实在请求之间保持了一点,因为 opcache 可以存储该文件的解析表示。例如将'<?php return ' . var_export($myArray, true) . ';\n' 放入一个文件中,一旦你加载了两次,第二次它就会来自 opcache 并且非常快。
猜你喜欢
  • 1970-01-01
  • 2017-09-08
  • 2014-12-30
  • 1970-01-01
  • 2013-05-12
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多