1

I'm working on a simple Ajax exercise where I separate the query, the Ajax, and the url that Ajax calls. In short, I run a query in one page and attach the resulting array to $_SESSION, then I display some html and the Ajax code calls a third page to get the elements from the array one by one via a counter attached to the $_GET superglobal. The three files are linked by require_once().

When the page loads initially, all is as expected. The $_SESSION contains the entire array pulled from MySQL, and the $_GET is null.

Once I click on the button to execute the Ajax code, the $_GET value changes and receives the value of the counter, as expected.

However, $_SESSION ceases to exist. The var_dump now returns null and I get an error Notice: Undefined variable: _SESSION in C:\wamp\www\.....\ajax.php. I don't understand why that is.

Here is my code. First, 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");
?>

Then the html and ajax code in 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>

And then the PHP that receives the array from $_SESSION and (should) return the next item based on the value of $_GET['index']. The file is 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

The problem is that session in ajax.php is not started / resumed.

When you call index.php, it is:

index.php -> .. -> ajax.php (SESSION EXISTS (session_start() called in index.php))

then you request your ajax.php through ajax:

html -> ajax.php (SESSION DOESNT EXISTS (session_start() was not ever called as we dont come from index.php))

You just need to initialize / resume session in your ajax.php, but you have to check if its not already initialized from index.php. Put this chunk of code into your ajax.php file:

if(!session_id())     // check if we have session_start() called
     session_start(); // if not, call it
于 2012-12-09T21:06:58.237 に答える
2

ajax.php needs a session_start() at the beginning, otherwise, when you call it standalone via ajax, you won't have a session, hence no $_SESSION var.

于 2012-12-08T01:26:23.430 に答える
2

From PHP DOC

session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.

When session_start() is called or when a session auto starts, PHP will call the open and read session save handlers. These will either be a built-in save handler provided by default or by PHP extensions (such as SQLite or Memcached); or can be custom handler as defined by session_set_save_handler(). The read callback will retrieve any existing session data (stored in a special serialized format) and will be unserialized and used to automatically populate the $_SESSION superglobal when the read callback returns the saved session data back to PHP session handling.

Without calling session_start definitely $_SESSION would not be populated accordingly why advice is to always call session_start if you in your script if you are going to be using sessions .

Quick Few steps

  1. Remove require_once ("ajax.php"); from index.php its not needed there

PHP CODE

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

From PHP DOC on mysql_query

Use of this extension is discouraged. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:

Your index.php should finally look like this

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, Your question has a very simple solution - Just add session_start() at the top of the ajax.php file.

However, the major problem here is lack of organization in your code structure.

Session / Configurations are preloaded in most of the actions. And these are included in a file which is loaded in every call.

Your file ajax.php apparently seems to be an independent file, however is dependent upon index.php, meanwhile index.php depends on ajax.php (require_once).

So the best work around for your type of code is as follows.

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 (Yes you need session_start() here, because when you make asynchronous request to this file, it acts as an independent request regardless of index.php. AJAX call is a client side asynchronous request, not a server side. )

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

viewUsers.php // since your viewUsers.php file isn't an independent file and is included by index.php only, you can simply add this line at the top to prevent direct invocation of the file.

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

PS: There isn't an unique solution. An approach is what you have to decide. Your approach is an approach, which isn't any kind of approach. Rest is fine.

I hope I have answered your queries.

Regards,

于 2012-12-11T15:38:10.637 に答える
0

You have a number of if conditions that are making it difficult for you to see errors. Add some echo statements at those locations to see what is happening in your program flow. It will be easier to troubleshoot. For example:

<?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>';
}

?>

Of course, you will remove those echo statements as you fix your code... They are only temporary, for debugging.

于 2012-12-06T18:14:13.950 に答える
0

I faced similar issue. I found that in one of the ajax call I forgot to call session_start(). when I ensured that I session_start() is always called in all the php code that are called thru ajax, then this problem went away.

于 2014-06-22T06:20:13.767 に答える
-1

When using AJAX sometimes the session is not carried over. In your AJAX post/get include the sessionID. Then on the receiving end do something like:

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

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

*Old-school method, yes, but tried and true.

于 2012-12-13T02:20:48.757 に答える