为什么这个PHP脚本(由AJAX调用)随机无法正确加载SESSION?

时间:2015-07-03 01:23:55

标签: php ajax session session-variables

Ahoy StackOverflow,

我在我的项目中遇到过这个问题:简而言之,从我收集的内容来看,通过AJAX调用的PHP脚本没有正确地注册在{{1的顶部设置的SESSION变量页面。起初,我认为这是由于会话锁定,所以我继续添加index.php,然而,这并没有解决问题。

此问题仅在新用户会话开始后大约25%的时间内发生(即:用户登录时)。

我继续删除了90%的代码,以便将错误降低到重现所需的最低编码。

来自Firebug的错误结果通过ajax.php

image

来自Firebug的预期结果通过ajax.php

image2

注意:两个结果都显示索引的session_write_close()作为print_r($_SESSION)返回,这让我知道问题不在索引页面上设置会话。

有没有人知道修复(甚至可能不是代码,甚至可能是服务器设置),它会正确地允许通过AJAX调用的脚本正确访问Session变量?

测试用于复制的方案

  1. 删除域
  2. 的所有Cookie
  3. 加载页面(最多2次)。 2次重新加载后,问题永远不会发生。
  4. 如果未显示不良结果,请重复步骤。
  5. 的index.php

    Array ( [userid] => 3724 [trialstatus] => 1 [trialtcompletions] => 0 [userlevel] => 5 )

    ajax.php

    <?php
    
    if (session_status() === PHP_SESSION_NONE) session_start();
    
    if (!isset($_SESSION['userid']))
    {
        $_SESSION['userid'] = 3724; //$login['AccountID'];
    }
    
    $_SESSION['trialstatus'] = "12";
    $_SESSION['trialtcompletions'] = "12";
    $_SESSION['userlevel'] = "12";
    session_write_close();
    
    print_r($_SESSION);
    ?>
    <!DOCTYPE html><html><head><script src="./js/jquery.min.js"></script>
    <script>
        function loadStage(step,input,callback){
            $.ajax({
                type: "POST",
                url: "./ajax.php",
                data: { step: step, input: input },
                dataType: "JSON",
                timeout: 5000,
                success: function(data){
                    if(data !== false){
                        callback(data);
                    }
                }
            });
        }
    
        $(document).ready(function(){
            startLoadingSequence();
        });
    
        function startLoadingSequence(skipped){
            loadStage(1,skipped,function(data){});
        }
    </script>
    </head></html>
    

    按要求:

    phpinfo

    阅读评论以获取更多信息

3 个答案:

答案 0 :(得分:11)

有两件事可能导致这个问题。

  1. 您在会话保存路径(df -h)中没有足够的空间,或者您的服务器没有权限进行保存。
  2. 您的服务器位于负载均衡器之后,您必须将会话保存在memcache或redis等持久后端中。

答案 1 :(得分:8)

如果您正在运行负载均衡器,那么您必须确保您的服务器正在达到数据的公共点。默认情况下,PHP将会话存储在本地文件系统中。如果负载均衡器将您从服务器A发送到服务器B(该文件不存在),那么这就成了问题。您可以设置网络共享并确保所有Web服务器都使用该共享。因此,您可以创建NFS共享,然后添加session_save_pathset it within php.ini

session_save_path('/your/nfs/share/here');

另一个选项是write your own session handler将会话放入数据库。然后,您可以使用memcached之类的东西来存储会话,这样您每次阅读会话数据时都不会破坏数据库。

答案 2 :(得分:1)

我所附的截图对于我运行的几乎所有25-30次运行都是相同的。   [1]:http://i.stack.imgur.com/MgLpS.jpg检查您的会话数据大小是否超过了缓存大小。或正在存储的一些其他会话数据耗尽了缓存内存。增加缓存大小可能会对您的方案有所帮助。