好的,所以这是我的第二次尝试,用一种新的,更加孤立和简洁的方式来展示问题。问题与登录系统有关,其中会话变量似乎在第一次尝试时没有保存。但这里是精简行为的精简代码:
<?php
session_start();
echo "POST superglobal: <pre>" . print_r($_POST, true) . "</pre><hr/>";
echo "SESSION superglobal: <pre>" . print_r($_SESSION, true) . "</pre><hr/>";
echo "COOKIE superglobal: <pre>" . print_r($_COOKIE, true) . "</pre><hr/>";
$_SESSION['session_var'] = "SESSION VAR AVAILABLE";
setcookie("cookie_var", "COOKIE VAR AVAILABLE");
?>
<html>
<body>
<form action="" name="frmPost" method="POST">
<input type="submit" name="cmdSubmitPost" value="Submit" />
</form>
</body>
</html>
在我本地计算机上的本地主机上,以下是此代码生成的内容:
初始页面加载后:
POST superglobal:
Array
(
)
SESSION superglobal:
Array
(
)
COOKIE superglobal:
Array
(
)
[Submit]
点击Submit
一次后:
POST superglobal:
Array
(
[cmdSubmitPost] => Submit
)
SESSION superglobal:
Array
(
[session_var] => SESSION VAR AVAILABLE
)
COOKIE superglobal:
Array
(
[cookie_var] => COOKIE VAR AVAILABLE
[PHPSESSID] => hpkpft4hh1tqlm6e3r496bt5j2
)
[Submit]
这正是我所期望和需要的。我还在两个单独的免费php托管网站上暂时注册来测试这个,他们都产生了与上面相同的结果。
然而,在Arvixe,我的主要托管环境,结果是不同的。就像这样:
初始页面加载后:
POST superglobal:
Array
(
)
SESSION superglobal:
Array
(
)
COOKIE superglobal:
Array
(
)
[Submit]
点击Submit
一次后:
POST superglobal:
Array
(
[cmdSubmitPost] => Submit
)
SESSION superglobal:
Array
(
)
COOKIE superglobal:
Array
(
)
[Submit]
点击Submit
第二次:
POST superglobal:
Array
(
[cmdSubmitPost] => Submit
)
SESSION superglobal:
Array
(
[session_var] => SESSION VAR AVAILABLE
)
COOKIE superglobal:
Array
(
[cookie_var] => COOKIE VAR AVAILABLE
[PHPSESSID] => 2k6ldfl2icdtj1k7sq5dc9qmj3
[VC-NoCache] => 1
[_asomcnc] => 1
)
[Submit]
我希望在localhost和其他临时免费php托管环境中创建的结果排除了相当简单的代码中的任何基本缺陷。
好的,现在问题:在Arvixe托管环境中,为什么页面在首次提交后无法识别cookie和会话值?我很确定真正的问题是为什么在第一次提交后cookie值无法识别? (这是真正的问题,因为这解释了会话值未被识别的原因......因为PHPSESSID cookie尚未被识别)。
php.ini值基本相同,但如果有特定值可能有助于在此发布,请告诉我哪些值。
另外,我认为这个问题的答案将有效地解决其他三个stackoverflow问题:
PHP cookie will not set until the page reloads TWICE. What's going on?
php session variable not stored at first attempt, working fine from second attempt
session variables not set the first time
(没有一个解决方案适合我)
答案 0 :(得分:0)
我在开发过程中遇到过这个问题几次,尽管我从未使用Arvixe
。我绝不是专家,但这是我所拥有的研究和经验以及超出编码错误的两个主要原因。
刷新页面时,新创建的Cookie无法立即生效。在使用SESSION_ID
和Cookie之前,我有过这种意外行为。例如,如果您在一个请求中设置了cookie,则在下一次请求服务器之前它将不可用(因此在您设置cookie之后进行下一次刷新)。
Accessing $_COOKIE immediately after setcookie()
也可能有奇怪的逻辑和浏览器缓存网页的方式,我认为这可能是这里发生的事情。
www
或non-www
问题你说它发生在你的Arvixe
环境而不是localhost?您应该在点击提交时检查域名(删除或添加www)是否正在更改。如果您在htaccess
中没有正确的规则或通过ini_set
或PHP中的其他配置设置进行设置,那么您可能会获得两个session_id。我无法从你的代码中清楚地说出来,但如果是这样的话,它就会解释为什么你只能第二次得到它(因为第一次提交它会加载新域并设置session
变量和{{1变量)。您的服务器可能会将cookie
视为新的子域,而不是选择共享cookie和session_id,而是创建一个新的子域。尝试进入www
并执行Console
以获取有关其是否正在发生变化的信息。
Allow php sessions to carry over to subdomains
document.cookie
命令或其他原因如果您在页面上有任何PHP命令,它们会调整session_id,例如重新生成它或者例如:
session_regenerate_id()
session_write_close()
这些命令可能会影响您的会话并导致意外行为。由于它是特定于案例的,因此在文档中进一步阅读会话的传播和处理方式符合您的最佳利益。除此之外,它可能是缓存,浏览器,标题,会话放置,陈旧会话,以前的cookie以及其他相关问题。
答案 1 :(得分:0)
如果代码完全相同,那么环境就是原因。做一个phpinfo();适用于不同的托管环境。复制生成的页面并运行差异比较。这将显示PHP的主机安装中可能存在的不公平。
通过查看您的代码,不完整或其他方式,没有人能够通过托管环境解决问题。
答案 2 :(得分:0)
感谢大家的投入。对于之后可能正在搜索此答案的任何人,事实证明问题是托管/服务器端。
实际切换主机(不仅仅是这个问题所需)后,我遇到了同样的问题。但是在新主机上,他们的服务器设置包括名为&#34; varnish caching&#34;这与客户端浏览器缓存非常不同。它是服务器端缓存。
据说它可以提高性能......但是如果你的应用程序在很大程度上依赖于经常变化的实时cookie和会话值,它真的会让事情变得混乱!
我敢打赌,我在原帖中上面链接的那些其他堆栈溢出帖是由此引起的。
在新的托管环境中,我刚关闭了所有&#34; varnish caching&#34;一切都运作良好。我怀疑旧主机有这样的服务器端缓存。