PHP会话变量似乎发生了变化';他自己的


PHP session variable appear to change on it's own

非常奇怪,我希望我只是忽略了一个小细节。我已经一行一行地查了好几天了,但还是不知所措。

因此,当我的页面加载时,我将一个随机变量设置为$_SESSION['rand_token'],然后将该值放在表单中的一个隐藏字段中。提交表单时,我会根据post值检查会话值,如果它们匹配,我会处理表单提交,如果它们不匹配,我继续加载页面(这意味着表单没有被处理,会话变量再次被更改,隐藏的表单输入得到了新的会话变量)。

问题是,会话变量在执行最后一行代码和执行第二行代码(第一行是session_start();(在表单提交之后)之间的某个时间发生了变化。我在代码的开头和结尾都有print_r($_SESSION);,可以看到这一点。

为什么变量在变化!?

<?php 
session_start(); 
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
if (isset($_SESSION['rand_token'], $_POST['rand_token'], $_SESSION['rand_token_expires'])) {
    if ($_SESSION['rand_token'] == $_POST['rand_token'] && time() < $_SESSION['rand_token_expires']) {
        //Process form
    } else {
        $danger_msg = 'Token Mismatch<br />Post: ' . $_POST['rand_token'] . '<br />Session: ' . $_SESSION['rand_token']; 
    }
}
$_SESSION['rand_token'] = md5(microtime(TRUE) . rand(0, 100000));
$_SESSION['rand_token_expires'] = time() + 60 * 60 * 1;
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
?>
<html>
<head>
<title></title>
</head>
<body>
<form>
    <input type="hidden" value="<?=$_SESSION['rand_token']?>" />
    <input type="submit" value="Submit" />
</form>
</body>
</html>

我将在随后的两次提交后向您显示结果:

第一次打印_r:4f3d097a6a760a4c579f8d8a5b355 ed

代币不匹配帖子:fd6bf788ed3d1393b07472f41b3efd1

令牌不匹配会话:4f3d097a6a760a4c579f8d8a5b355 ed

第二次打印_r:053f22d6126130e88f355fbc5cbbde1f


第一次打印_r:279a85854fc6362d8dc52b0b74d30ef7

代币不匹配帖子:053f22d6126130e88f355fbc5cbbde1f

令牌不匹配会话:279a85854fc6362d8dc52b0b74d30ef7

第二次打印_r:edbee2d6cedbf5581920af353754fed8

我知道这有点令人困惑,但您会看到第二个print_r应该与下一个第一个print_r相同。为什么会改变?!

我最近经历了同样的事情,在我的情况下,特别是对于使用时间函数生成的令牌,如果其中一个资产调用在返回404的页面上,它显然重新生成了令牌。因此,检查页面是否有对资产返回404的调用。

这不是一个真正的答案,但您的代码中存在一些错误。我已经更新了它,它运行得非常好:

<?php 
session_start(); 
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
if (isset($_SESSION['rand_token'], $_POST['rand_token'], $_SESSION['rand_token_expires'])) {
    if ($_SESSION['rand_token'] == $_POST['rand_token'] && time() < $_SESSION['rand_token_expires']) {
        echo "Form should be submitted.";
    } else {
        $danger_msg = 'Token Mismatch<br />Post: ' . $_POST['rand_token'] . '<br />Session: ' . $_SESSION['rand_token']; 
        echo $danger_msg;
    }
}
$_SESSION['rand_token'] = md5(microtime(TRUE) . rand(0, 100000));
$_SESSION['rand_token_expires'] = time() + 60 * 60 * 1;
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
?>
<html>
<head>
<title></title>
</head>
<body>
<form method="post" action=""> <!-- forgot to set form to post here, defaulted to get instead -->
    <input type="hidden" name="rand_token" value="<?=$_SESSION['rand_token']?>" /> <!-- forgot to set name="" here -->
    <input type="submit" value="Submit" />
</form>
</body>
</html>