7

我有一个依赖于请求之间的某些状态信息的 API。作为代码的一个简单的第一个版本,我只是使用 PHP 会话来存储状态信息,而不是更高级的东西(APC、memcache、DB)。在我在网络浏览器中进行的初始测试中,一切都运行良好。但是,当客户端尝试通过非浏览器方法(例如 Curl 或 wget)进行连接时,似乎没有保留状态信息。

只有在浏览器请求页面时才会创建 PHP 会话吗?我明确地使用 session_start() 开始会话,并使用 session_name() 预先命名它。

一个补充说明。我了解到我遇到的主要问题之一是我正在命名会话而不是通过 session_id($id); 设置会话 ID;我使用 session_name() 的目的是检索之前创建的同一会话,正确的方法是设置 session_id 而不是 session_name。

似乎会话信息将保留在服务器上,如下所述(谢谢)。但要保持这一点,您必须传递会话 id,或者,在我的情况下,任何其他可以唯一标识用户的 id。将此 id 用作 session_id,您的会话将按预期运行。

4

3 回答 3

21

会话 Cookie

请记住,HTTP 是无状态的,因此在您的服务器上跟踪会话,但客户端必须在每个请求中识别自己。当您声明 session_start() 时,您的浏览器通常会设置一个 cookie(“PHP 会话 ID”),然后通过在每个请求中发送 cookie 值来标识自己。当使用带有会话值的请求调用脚本时, session_start() 函数将尝试查找会话。为了向自己证明这一点,请注意,当您清除 cookie 时会话会终止。如果 cookie 是“会话”cookie(临时的),即使您退出浏览器,许多会话也会终止。您提到您正在为会话命名。查看您的浏览器 cookie 并查看是否可以找到具有相同名称的 cookie。

所有这一切都是说 cookie 在您的会话中发挥着积极作用,因此如果客户端不支持 cookie,那么您将无法按照当前的方式进行会话.. 至少对于那些替代客户。将在服务器上创建一个会话;问题是客户是否参与。

如果 cookie 不是您的客户端的选项,您将不得不找到另一种方法将会话id 传递给服务器。例如,这可以在查询字符串中完成,尽管以这种方式发送会话 id 被认为不那么私密。

mysite.com?PHPSESSID=10alksdjfq9e

具体如何做到这一点可能会因您的 PHP 版本而异,但它基本上只是一个配置。如果设置了正确的运行时选项,PHP 将透明地将会话 ID 作为查询参数添加到页面上的链接(当然,仅限同源)。您可以在PHP 网站上找到设置的详细信息。

旁注:多年前,这是尝试实现会话时的常见问题。Cookie 较新,许多人出于所谓的安全问题而关闭了浏览器中的 cookie 支持。

旁注: @Uberfuzzy提出了一个很好的观点——实际上可以使用带有 curl 或 wget 的会话。问题是它的自动化程度较低。用户可能会将标头值转储到文件中并在将来的请求中使用这些值。curl 有一些“cookie 意识”标志,可以让您更轻松地处理这个问题,但您仍然必须明确地这样做。再说一次,你可以利用它来发挥你的优势。如果 curl 在您的替代客户端上可用,那么您可以使用 cookie 感知标志合理地自己拨打电话。请参阅卷曲手册

于 2008-10-04T09:17:55.970 回答
2

如果您调用 session_start(),那么如果客户端不在现有会话中,则会创建一个会话。如果客户端不支持(或配置为忽略)用于维护会话的 cookie 或查询字符串机制,则会在每个请求上创建一个新会话。

这可能会使您的会话存储机制因未使用的会话而膨胀。

如果您觉得这可能是个问题,那么最好只在会话中存储一些内容(例如,用户登录或机器人不太可能做的其他事情)时调用 session_start()。

于 2008-10-04T10:50:46.267 回答
2

只有在浏览器请求页面时才会创建 PHP 会话吗?

简短的回答:是的。会话是专门为利用浏览器功能解决 HTTP 无状态问题而创建的。APC、memcached、DB 等无关紧要。这些只是会话的存储方法,并且会遇到同样的问题。

更长的答案:创建会话的概念是为了说明 HTTP 是一种无状态协议这一事实,事实证明,状态对于各种软件应用程序非常重要。

实现会话的最常见方式是使用 cookie。PHP 在 cookie 中发送会话 ID,浏览器将带有会话 ID 的 cookie 发送回。此 ID 在服务器上用于查找您在会话中存储的任何信息。PHP 能够在 URL 的末尾包含和读取会话 ID,但这假设用户将通过单击包含生成的会话 ID 的链接导航到您的站点/应用程序上的页面。

在您的特定情况下,可以将 cookie 与 curl(可能还有 wget)一起使用。Curl一个网络浏览器,只是一个没有 GUI 的浏览器。如果它是您正在使用的命令行 curl 程序(而不是 C 库、PHP 扩展等),请阅读以下选项

-b/--cookie
-c/--cookie-jar
-j/--junk-session-cookies
于 2008-10-04T18:00:04.980 回答