当会话因超时或关闭浏览器而被破坏时,有没有办法执行函数?
是的,但它可能不像你想象的那样工作。您可以使用 定义自己的自定义会话处理程序session_set_save_handler
,并且定义的一部分是提供destroy
和gc
回调函数。这两个在会话被显式销毁以及由于过期而被销毁时被调用,因此它们完全按照您的要求执行。
但是,由于超时而导致的会话到期不会以发条精度发生;过期会话实际上是“垃圾收集”可能需要很长时间。此外,垃圾收集是概率性触发的,因此理论上过期会话有可能永远不会被垃圾收集。
这有道理吗?对于共享服务器来说,几百个并发 SQL 查询是否会成为问题,并且使用 $_SESSION 作为缓冲区的想法可以缓解其中的一些问题。
我真的不会这样做有几个原因:
- 过早的优化(在你测量之前,不要只是假设它会“更好”)。
- 会话可能永远不会被垃圾收集;即使这没有发生,您也无法控制它们何时被收集。这可能是个问题。
- 有可能丢失会话包含的所有内容(例如服务器重新启动),其中包括玩家进度。玩家不喜欢失去进度。
- 同一用户的并发会话是不可能的(谁的“保存的数据”获胜并保留在数据库中?)。
替代品呢?
好吧,既然我们谈论的是便宜的共享主机,你肯定不会控制服务器,所以任何涉及 PHP 扩展(例如 memcached)的东西都是有条件的。数据库端缓存也不会飞。此外,您的服务器上的负载将受到您无法控制的变量的影响,因此您无法真正进行任何容量规划。
在任何情况下,我都会首先确保数据库本身的结构是最佳的,并且代码的编写方式可以最大限度地减少数据库的负载(只需在编辑器中输入内容即可释放性能)。
之后,您可以引入只读缓存:通常有很多东西需要显示但不打算修改。对于“几乎永远不会”更新的数据,您可以在需要时使会话缓存失效,这可能是一个简单且非常有效的改进(您甚至可以在失效方面出现误报,只要它们在宏伟的计划)。
最后,如果您担心在单个请求中两次从数据库中提取相同的数据,您可以添加每个请求的缓存(在变量中)。