【发布时间】:2015-09-12 13:48:19
【问题描述】:
好的,这是我的第二次尝试,用一种新的、更加孤立和简洁的方式来展示这个问题。问题与登录系统有关,其中会话变量似乎在第一次尝试时没有保存。但这里是演示错误行为的精简代码:
<?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
(那里的解决方案都不适合我)
【问题讨论】:
-
我认为您应该包含完整的代码,而不是条带化的代码(仅是相对的),因为这看起来像是某种其他错误逻辑的条件
-
但是完整的代码非常庞大。这基本上是我将隐藏字段写入包含令牌的表单的情况,该令牌也写入会话。然后当表单发布时,我比较两者以确保帖子来自我的表单(即防止 CSRF 攻击)。它总是在第一次通过后返回“无效”(因为它没有看到会话变量)。第二次起作用了。与这里的精简(但功能齐全的代码)相同。在这里我们绝对可以看到失败。
-
我在这里提出的案例排除了错误的逻辑,因为它在 localhost 和其他两个测试 php 主机环境中的功能完全符合预期。