【问题标题】:Old PHP session variable is loaded sometimes有时会加载旧的 PHP 会话变量
【发布时间】:2012-06-25 03:09:34
【问题描述】:

我有一个页面,其中包含一些用户可选择的选项和一个按钮,单击该按钮会运行 PHP 脚本,然后使用另一个 PHP 文件刷新 div,该文件使用在第一个 PHP 脚本末尾创建的会话变量。如果用户再次按下按钮,选择了不同的选项,则使用新替换的会话变量更新 div。问题是,有时,可能 10 次左右有 1 次会加载旧的会话变量数据。我怀疑第二个 PHP 文件在更新之前太早地捕获了该变量,但我尝试在各个点取消设置会话变量,但没有任何运气。

第一个 PHP 文件:

session_start();
$needle = array();
foreach($_POST['checkboxes'] as $key => $value){
$needle[] = "$value";
}
// code that processes the values from needle and outputs $data
unset($_SESSION['data']);
$_SESSION['data']=$data;

第二个 PHP 文件:

session_start();
echo $_SESSION['data'];

Javascript:

$(".userdata").click(function() {
   $.post("first.php", $("form#checkboxes").serialize());
});
$(function() {
   $("#button").click(function() {
   $("#div").load('second.php')
   })
})

【问题讨论】:

  • 请显示代码。很难说否则会发生什么。
  • 会话是否存储在数据库中?
  • 如果你使用session_destroy会发生什么?
  • 你能发布涉及的javascript吗?假设您使用的是 Ajax(基于此问题的标签),您应该确保 PHP 脚本在更新 div 的 javascript 之前已完全运行。具体来说,您应该确保更新 div 的 javascript 代码是您链接到调用第一个 PHP 脚本的代码的“成功”ajax 回调的一部分。

标签: php javascript jquery


【解决方案1】:

问题在于,在某些情况下,在您单击加载第二个 PHP 脚本的按钮之前,第一个 PHP 脚本尚未完成运行(就像我之前在评论中暗示的那样)。发生这种情况的事实与网络服务器如何调度脚本有关(这完全是一个不同的主题)。

因此,您需要确保当您单击运行第二个脚本的按钮时,第一个脚本已完全运行完毕。

因为据我所知,javascript 不允许对变量进行阻塞/发送信号(就像 Java 一样),您将不得不使用一种更“肮脏”的技术,称为忙等待。

最好的方法是在您使用的 javascript 中包含一个额外的变量。

var wait = false;
function reloadSecond (){
  if (wait){
    setTimeout('reloadSecond()',200);
  } else {
    $("#div").load('second.php');
  }  
}

$(".userdata").click(function() {
   wait = true;
   $.post("first.php", $("form#checkboxes").serialize(), function(){
     wait = false;
   });

});
$(function() {
   $("#button").click(reloadSecond);
})

虽然“忙等待”通常不被认为是最优雅的解决方案,但我认为在这种情况下您没有很多其他选择(除了服务器端推送,它要复杂得多)。此外,您可能只会产生一两次额外的 200 毫秒(或更短,您当然可以更改此值)等待时间。

(旁注:我假设这里的 javascript 是单线程的,几乎在所有情况下都是如此:Is JavaScript guaranteed to be single-threaded?)。

【讨论】:

  • 我认为是。如果将调用 div 更新的 click 处理程序放在回调中,则只有在调用回调后才会起作用。这意味着如果您在调用回调之前单击调用第二个 PHP 脚本 (#button) 的按钮,则不会发生任何事情。这将导致您之前遇到的相同行为(第二个按钮在大多数情况下有效,但在某些情况下 - 如果服务器端调度不是按时间顺序排列的 - 它不会)。
  • 是的,这将是一个更默认的用例,并且将始终有效 - 假设 PHP 脚本中没有发生错误(仅供参考,您可以查看 jquery 的 ajax 错误回调来处理该问题 -虽然不是强制性的)。
【解决方案2】:

可能是浏览器或代理服务器正在缓存 html 数据的情况吗?尝试设置标题以告诉他们不要缓存。请参阅http://php.net/manual/en/function.header.php 中的示例了解要设置的标头。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 2013-05-01
    • 2011-06-09
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多