我有一个 Web 应用程序,它在用户会话中存储一些对象,因此每次 AJAX 命中服务器时它都不必继续调用数据库。
我想编写一些在用户关闭浏览器选项卡或导航离开页面时触发的清理/保存功能。
如果用户导航离开页面,会话是否“被破坏”(即调用 __destruct 它包含的任何对象) - 还是使用在用户导航离开时发送 AJAX 请求的 javascript 处理这个客户端更好?
PHP 会话是服务器端的东西。如果您没有显式地进行 AJAX 调用或类似调用,则客户端浏览器从页面导航不会触发任何服务器端。
简而言之:没有。你必须结束你的会话session_destroy()
会话在 PHP 中没有定义为一个类。相反,我们有一组会话函数来操作会话。为确保您已销毁会话,您需要显式调用:
session_destroy();
如果您没有销毁会话,会话将在会话超时后进行垃圾收集。垃圾收集取决于以下参数 - session.gc_maxlifetime、session.gc_divisor 和 session.gc_probability。为了确保垃圾收集在每个会话上运行,您必须将 session.gc_probability 添加到 100%。但这肯定会增加服务器的开销,特别是如果您的服务器是高流量服务器。
如果您没有明确跟踪会话并在使用后将其销毁,那么您会将会话管理的某些部分留给操作系统。请参阅 PHP.net 的注释:
注意:如果您使用默认的基于文件的会话处理程序,您的文件系统必须跟踪访问时间 (atime)。Windows FAT 不支持,因此如果您遇到 FAT 文件系统或任何其他时间跟踪不可用的文件系统,您将不得不想出另一种方法来处理垃圾收集会话。从 PHP 4.2.3 开始,它使用 mtime(修改日期)而不是 atime。因此,您不会遇到时间跟踪不可用的文件系统问题。
最好的方法是在浏览器或选项卡关闭时通过 Ajax 调用发送一个标志。您可以通过 javascript 的window.onunload事件来检测它 。
如果将任何对象放入$_SESSION
中,则脚本结束时不会调用它们的析构函数,但如果存在,__sleep()
则在 PHP 序列化 $_SESSION 时调用魔术函数。当下一个脚本再次启动会话时,任何已存储且其源代码已知的对象(例如,在调用 session_start() 之前要求它,或使用自动加载)都将__wakeup()
调用该方法。
如果 PHP 检测到会话在一段时间内处于非活动状态,它会简单地删除序列化文件。
请参阅文档: http: //php.net/manual/en/language.oop5.magic.php