在我的PHP + Ajax代码中,为什么$ _SESSION在执行期间会消失?

时间:2012-12-06 00:50:47

标签: php ajax

我正在进行一个简单的Ajax练习,我将查询,Ajax和Ajax调用的url分开。简而言之,我在一个页面中运行查询并将结果数组附加到$_SESSION,然后我显示一些html,Ajax代码调用第三页以通过附加到的计数器逐个从数组中获取元素$_GET超全球。这三个文件由require_once()链接。

最初加载页面时,所有内容都符合预期。 $_SESSION包含从MySQL中提取的整个数组,$_GET为空。

一旦我点击按钮执行Ajax代码,$_GET值就会发生变化并按预期接收计数器的值。

但是,$_SESSION不再存在。 var_dump现在返回null,我收到错误Notice: Undefined variable: _SESSION in C:\wamp\www\.....\ajax.php。我不明白为什么会这样。

这是我的代码。首先,index.php

<?php

session_start();

$dbhost = "localhost";
$dbuser = "admin";
$dbpass = "XXXXXXX";
$dbname = "test";
mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($dbname) or die(mysql_error());
$query = "SELECT ae_name FROM ajax_example";
$qry_result = mysql_query($query) or die(mysql_error());
$result;
while($row = mysql_fetch_array($qry_result,MYSQL_ASSOC)){
    $result[]=$row;
}

$_SESSION['array']=$result;

require_once ("viewUsers.php");

require_once ("ajax.php");
?>

然后是viewUsers.php中的html和ajax代码:

<html>
<body>
<script type="text/javascript">
<!-- 
function createRequest() {
    try {
      request = new XMLHttpRequest();
    } catch (tryMS) {
      try {
        request = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (otherMS) {
        try {
          request = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (failed) {
          request = null;
        }
      }
    }
    return request;
  }
var indx=0;
function calcIndex(){
  return indx++;
}
function ajax(){
  ajaxRequest = createRequest();
  var index=calcIndex();
  var url="ajax.php?index=" + index;
  ajaxRequest.open("GET",url, true);
  ajaxRequest.onreadystatechange = display;
  ajaxRequest.send(null); 
}
function display(){
  if(ajaxRequest.readyState == 4){
    var ajaxDisplay = document.getElementById('ajaxDiv');
    ajaxDisplay.innerHTML = ajaxRequest.responseText;
  }
}
//-->
</script>
<form name='myForm'>
<input type='button' onclick='ajax()' value='Show next name' />
</form>
<div id='ajaxDiv'>Your result will be displayed here</div>
</body>
</html>

然后从$ _SESSION接收数组的PHP和(应该)根据$ _GET ['index']的值返回下一个项目。该文件为ajax.php

<?php
var_dump('Get value in ajax.php',$_GET); // The values are as expected
var_dump('Session value in ajax.php',$_SESSION); // This global cease to exist after I click the button
if(isset($_SESSION['array'])){
  $array=$_SESSION['array'];
  $cnt=count($array);
  $index=null;
  if(isset($_GET['index'])){
    $index=$_GET['index'];
    if($index>=$cnt){
      $str="And that's it....";
    }else{
    $str="The next name is ".$array[$index]['ae_name'];
    }
    echo $str;
  }
}
?>

7 个答案:

答案 0 :(得分:18)

问题是ajax.php中的会话未启动/恢复。

当你调用index.php时,它是:

index.php - &gt; .. - &gt; ajax.php( SESSION EXISTS(在index.php中调用session_start())

然后您通过ajax:

请求ajax.php

html - &gt; ajax.php( SESSION DOESNT EXISTS(之前没有调用session_start(),因为我们不是来自index.php)

您只需要在ajax.php中初始化/恢复会话,但是您必须检查它是否已从index.php初始化。将这段代码放入ajax.php文件中:

if(!session_id())     // check if we have session_start() called
     session_start(); // if not, call it

答案 1 :(得分:2)

ajax.php在开头需要一个session_start(),否则,当你通过ajax单独调用它时,你将没有会话,因此没有$ _SESSION var。

答案 2 :(得分:2)

来自PHP DOC

  

session_start()根据通过GET或POST请求传递的会话标识符创建会话或恢复当前会话,或通过cookie传递。

     

当调用session_start()或会话自动启动时,PHP将调用open和read会话保存处理程序。这些将是默认提供的内置保存处理程序或PHP扩展(如SQLite或Memcached);或者可以是session_set_save_handler()定义的自定义处理程序。读取回调将检索任何现有的会话数据(以特殊的序列化格式存储)并且将被反序列化并用于在读取回调将已保存的会话数据返回到PHP会话时自动填充$ _SESSION超全局处理

如果你打算使用会话,如果在你的脚本中,为什么建议总是调用session_start,那么不会相应地调用session_start $_SESSION

快速步骤

  1. require_once ("ajax.php");移除index.php
  2. PHP代码

    $_SESSION['array']=$result;
    require_once ("viewUsers.php");
    require_once ("ajax.php");  //<------ remove this 
    
    1. session_start();添加到ajax.php
    2. 来自mysql_query

      的PHP DOC

        

      不鼓励使用此扩展程序。相反,应使用MySQLiPDO_MySQL扩展名。另请参阅MySQL:选择API指南和相关的常见问题解答以获取更多信息。此功能的替代方案包括:

      你的index.php最终应该是这样的

      session_start();
      
      // Put this in config file 
      $dbhost = "localhost";
      $dbuser = "admin";
      $dbpass = "XXXXXXX";
      $dbname = "test";
      $array = array();
      
      //Start DB Connection 
      $mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
      $query = "SELECT ae_name FROM ajax_example";
      $result = $mysqli->query($query);
      
      //Get Information
      while ( $row = $result->fetch_assoc() ) {
          $array[] = $row;
      }
      
      $result->free();
      $mysqli->close();
      
      // Add Info to session 
      $_SESSION['array'] = $array;
      require_once ("viewUsers.php");
      

答案 3 :(得分:2)

@JDelage, 您的问题有一个非常简单的解决方案 - 只需在ajax.php文件的顶部添加session_start()即可。

但是,这里的主要问题是代码结构中缺乏组织。

在大多数操作中预加载会话/配置。这些都包含在每个调用中加载的文件中。

您的文件ajax.php显然似乎是一个独立的文件,但是依赖于index.php,同时index.php依赖于ajax.php(require_once)。

因此,您的代码类型的最佳解决方法如下。

bootstrap.php中

<?php
// just to check to prevent overwriting of your configs / preloads.
if(!defined("INITIALIZED")){
  session_start();
  //.. some other basic settings if you require
  define("INITIALIZED", 1);
}
?>

的index.php

<?php
include_once "bootstrap.php";
// .. your code
require_once("viewUsers.php");
require_once("ajax.php");

ajax.php(是的,你需要session_start(),因为当你对这个文件发出异步请求时,无论index.php如何,它都是一个独立的请求.AJAX调用是客户端异步请求,而不是服务器端。)

<?php
include_once 'bootstrap.php';
// .. your code

viewUsers.php //因为您的viewUsers.php文件不是一个独立的文件,仅由index.php包含,您可以在顶部添加此行以防止直接调用该文件。

<?php
if(!defined("INITIALIZED")){die();}

PS: 没有一个独特的解决方案。你需要决定一种方法。你的方法是一种方法,这不是任何一种方法。休息很好。

我希望我已经回答了您的问题。

问候,

答案 4 :(得分:0)

您有许多if条件,使您很难看到错误。在这些位置添加一些echo语句,以查看程序流程中发生的情况。排除故障会更容易。例如:

<?php

//session_start();

echo 'You sent ' . $_GET['index'] . '<br>'; //Ensure index value arriving

if(isset($_SESSION['array'])){
    $array=$_SESSION['array'];
    $cnt=count($array);
    $index=null;
    if(isset($_GET['index'])){
        $index=$_GET['index'];
        echo 'Got to here<br>';  //Another checkpoint - send something back
        if($index>=$cnt){
            $str="And that's it....";
        }else{
            $str="The next name is ".$array[$index]['ae_name'];
        }
        echo $str;
    }else{
        echo 'GET var "index" was not set<br>';
    }
}else{
    echo 'SESSION var "array" was not set<br>';
}

?>

当然,您将在修复代码时删除这些echo语句...它们只是临时的,用于调试。

答案 5 :(得分:0)

我遇到了类似的问题。我发现在其中一个ajax调用中我忘了拨打session_start()。 当我确保总是在所有通过ajax调用的php代码中调用session_start()时,这个问题就消失了。

答案 6 :(得分:-1)

有时使用AJAX时,会话不会被转移。在您的AJAX帖子/ get中包含sessionID。然后在接收端做类似的事情:

$sid = ($_POST['sid']) ? $_POST['sid'] : '';    //Check for posted session ID

session_start($sid);  //Start session using posted ID or start new session

*老派的方法,是的,但是尝试过并且是真的。