【问题标题】:Sessions (PHP) and how they interact with each other会话 (PHP) 以及它们如何相互交互
【发布时间】:2016-02-08 22:05:14
【问题描述】:

这是一个关于 php 中会话的问题。

我有页面A.phpC.phpD.phpA.php 正在显示内容 A,登录时我希望 A.php 显示内容 B,当从页面 A.php 移动到页面 D.php 再到 A.php 时,它显示内容 A 而不是内容 B。

页面A.phpC.phpD.php都是通过ajax通信的。

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

【问题讨论】:

标签: php ajax session


【解决方案1】:

TL;DR;

你不应该。

仅仅因为你的问题不是会话而是竞争条件。


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

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

PHP 中的默认会话处理程序将锁定从调用session_start() 直到脚本结束或调用session_write_close() 的活动会话。此排他锁可防止解释器的任何其他实例读取或写入此会话文件,直到该锁被释放(为了防止会话中的损坏)。这意味着对同一会话的并发请求将被阻塞。但是,这仅在从多个并发 HTTP 请求(例如多个异步 - AJAX - 请求的情况下)访问 same 会话时才会出现问题。 p>

换句话说,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 秒的时间来加载。现在您的网络服务器有一个队列备份,其中包含多个请求,这些请求都将相互阻塞,因为它们都将要求同一个会话。如果没有仔细计划,您会发现这会成为一个越来越严重的问题。


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

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

【讨论】:

    猜你喜欢
    • 2018-11-26
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2012-06-23
    相关资源
    最近更新 更多