会话(PHP)以及它们如何相互交互

时间:2015-11-07 23:46:31

标签: php ajax session

这是关于php会话的问题。

我有Page A.phpC.phpD.phpA.php正在显示内容A,登录后我希望A.php显示内容B,从网页A.php移至网页D.php,然后再移至A.php显示内容A而不是内容B.

网页A.php C.phpD.php都通过ajax进行通信。

我想知道如何使用ajax检查会话是否正在页面A.php上进行,以便显示内容B而不是内容A.

1 个答案:

答案 0 :(得分:1)

TL; DR;

你不应该。

只是因为你的问题不是会话,所以它是竞争条件。

首先,需要明确 HTTP请求 PHP脚本之间的区别。每个HTTP请求都可以调用多个PHP脚本(,例如,一个脚本包含同一请求中的另一个脚本)。但是,对相同或不同脚本的多个HTTP请求始终在其自己的隔离环境中运行(,其中没有请求与另一个请求共享信息)。这是构建PHP的 share-nothing 体系结构,在处理PHP服务器端会话时理解这个概念很重要。

认识到每个用户通常在服务器上都有自己的会话文件也很重要。因此,无论有多少脚本在单个请求中使用该会话 ,多个用户的并发请求通常都不是问题。

multiple-sessions

PHP中的默认会话处理程序将从调用session_start()的那一刻起锁定一个活动会话,直到脚本结束或调用session_write_close()为止。此独占锁可防止解释器的任何其他实例在释放锁之前能够读取或写入此会话文件(以防止会话中的损坏)。这意味着对同一会话的并发请求将被阻止。但是,当从多个并发HTTP请求(例如,在多个异步 - AJAX - 请求的情况下)访问相同的会话时,这只是一个问题。

multiple-requests

换句话说,PHP使您可以安全地跨多个并发请求透明地使用会话,而不必担心会破坏会话的并发模型。

但是,这并不意味着您应该依赖会话来实现并发目的。

让我举一个你可以自己设计的竞赛条件的例子。用户登陆您的主页www.example.com,其中A.php启动会话(并说用户未登录)。现在,用户尝试登录(例如,C.php是负责登录/身份验证的脚本,通过AJAX调用)。假设C.php在登录后将用户重定向回主页(典型的PRG场景)。当A.php再次加载时,它正在使用会话并锁定它。假设另一个AJAX请求在后台触发到B.php,它也需要会话。它必须等待A.php释放锁定或结束才能执行任何操作。所以现在它处于阻塞状态,直到锁被释放。

如果您的请求在合理的时间内(通常只有几分之一秒)加载,这些问题通常无关紧要。然而,它们确实会产生连锁效应。

假设您的javascript有一个setInterval()回调,每5秒调用一次B.php。现在让我们假设您的服务器突然被请求所淹没,而B.php现在需要大约6秒才能加载。现在,您的Web服务器有一个备份的队列,其中包含多个请求,这些请求将全部阻塞,因为它们都要求同一个会话。如果不仔细计划,你可以看到这会成为越来越多的问题。

会话通常用作通过无状态协议(即HTTP )保持有状态信息的方法。这通常适用于跟踪用户身份验证/登录,他们可能已保存在您网站上的偏好或购物车结帐信息等内容......

  

您真正不应该依赖会话的是跟踪超出单个请求的状态。这意味着,如果您想使用会话来确定用户是否正在进行其他并发请求,或者检查此用户的即时请求之外的其他会话,那么您实际上正在打破PHP围绕其设计的一些架构限制,并且可能会遇到意想不到的失败。