1

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

最初加载页面时,一切都按预期进行。$_SESSION包含从 MySQL 中提取的整个数组,并且为$_GETnull。

一旦我单击按钮执行 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");
?>

然后是 html 和 ajax 代码viewUsers.php

<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>

然后 PHP 从 $_SESSION 接收数组并(应该)根据 $_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;
  }
}
?>
4

7 回答 7

18

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

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

index.php -> .. -> ajax.php(会话存在(在 index.php 中调用 session_start())

然后你ajax.php通过ajax请求你:

html -> ajax.php(会话不存在(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
于 2012-12-09T21:06:58.237 回答
2

来自 PHP 文档

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

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

没有调用session_start肯定$_SESSION不会相应地填充为什么建议总是调用 session_start 如果你在你的脚本中,如果你要使用 session 。

快速几个步骤

  1. require_once ("ajax.php");那里index.php不需要

PHP代码

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

来自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");
于 2012-12-11T14:29:31.387 回答
2

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

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

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

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

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

引导程序.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);
}
?>

索引.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:没有唯一的解决方案。方法是您必须决定的。你的方法是一种方法,它不是任何一种方法。休息就好。

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

问候,

于 2012-12-11T15:38:10.637 回答
2

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

于 2012-12-08T01:26:23.430 回答
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在修复代码时删除这些语句......它们只是临时的,用于调试。

于 2012-12-06T18:14:13.950 回答
0

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

于 2014-06-22T06:20:13.767 回答
-1

使用 AJAX 时,有时会话不会继续。在您的 AJAX 发布/获取中包含 sessionID。然后在接收端执行以下操作:

$sid = ($_POST['sid']) ?$_POST['sid'] : ''; //检查发布的会话ID

session_start($sid); //使用发布的ID开始会话或开始新的会话

*老派的方法,是的,但经过验证是正确的。

于 2012-12-13T02:20:48.757 回答