PHP:在$ _SESSION中存储"对象"
我只是想知道我实际上可以将对象存储在$ _SESSION中,我发现它很酷,因为当我跳到另一页时,我仍然有我的对象。现在,在我开始使用这种方法之前,我想了解一下这是否真的是一个好主意,或者是否存在潜在的陷阱。
我知道,如果我只有一个入口点,就不需要这样做,但是我还没有,所以我还没有一个入口点,所以我很想保留自己的对象,因为我那样不会失去我的状态。 (现在,我还读过我应该对无状态站点进行编程,但是我还不了解这个概念。)
简而言之:将对象存储在会话中可以吗,这有什么问题吗?
编辑:
临时摘要:到目前为止,我知道重新创建对象可能更好,即使它涉及再次查询数据库。
进一步的答案可能会在这方面详细说明!
解决方案
只要在进行session_start()调用时,PHP已经遇到过类声明/定义,或者已经安装的自动加载器可以找到它,就可以。否则,它将无法从会话存储反序列化对象。
HTTP是无状态协议,这是有原因的。会话将状态焊接到HTTP上。根据经验,请避免使用会话状态。
更新:
在HTTP级别上没有会话的概念。服务器通过为客户端提供唯一的ID并告诉客户端在每次请求时重新提交来提供此功能。然后,服务器使用该ID作为大型Session对象哈希表的密钥。每当服务器收到请求时,它都会根据客户端随请求提交的ID从会话对象的哈希表中查找会话信息。所有这些额外的工作对可伸缩性是双重打击(这是HTTP无状态的一个重要原因)。
- Whammy One:它减少了单个服务器可以完成的工作。
- 异想天开二:这使得扩展变得更加困难,因为现在我们不能只将请求路由到任何旧服务器-它们没有相同的会话。我们可以将具有给定会话ID的所有请求固定到同一服务器。这并不容易,而且是单点故障(不是针对整个系统,而是针对大量用户)。或者,我们可以在群集中的所有服务器之间共享会话存储,但是现在我们有了更多的复杂性:网络连接的内存,独立的会话服务器等。
考虑到所有这些,我们在会话中输入的信息越多,对性能的影响就越大(正如Vinko指出的那样)。另外,正如Vinko指出的那样,如果对象不可序列化,则会话将无法正常运行。因此,根据经验,避免在会话中添加超出绝对必要的内容。
@Vinko通常,我们可以通过将要跟踪的数据嵌入到发送回的响应中,然后让客户端重新提交它,例如,将数据向下发送到隐藏输入中,来解决服务器存储状态的问题。如果我们确实需要服务器端状态跟踪,则可能应该在后备数据存储区中。
(Vinko补充:PHP可以使用数据库来存储会话信息,让客户端每次重新提交数据可能会解决潜在的可伸缩性问题,但是由于客户端可以控制所有事务,因此我们必须注意一大堆安全问题国家)
- 无法序列化的对象(或者包含无法序列化的成员)将不会像我们期望的那样从$ _SESSION中退出
- 巨大的会话给服务器增加了负担(每次对状态信息进行序列化和反序列化都是很昂贵的)
除此之外,我还没有发现任何问题。
我们必须记住,资源类型(例如db连接或者文件指针)在页面加载之间不会持久存在,并且我们需要无形地重新创建它们。
还请考虑会话的大小,具体取决于会话的存储方式,大小限制或者延迟问题。
我建议不要使用状态,除非我们绝对需要它。如果可以在不使用会话的情况下重建对象,请执行此操作。
在Web应用程序中具有状态会使应用程序的构建更加复杂,对于每个请求,我们都必须查看用户处于何种状态。网络应用程序)。
最后,我建议我们将会话对象保持尽可能小,因为这会影响序列化和反序列化大对象的性能。
以我的经验,对于比具有某些属性的StdClass更复杂的事情,通常不值得这样做。给定会话存储的标识符,反序列化的成本始终比从数据库重新创建的成本高。看起来很酷,但是(像往常一样),概要分析是关键。