Solved

$_SESSION Disappearing in PHP script

Posted on 2012-03-14
25
491 Views
Last Modified: 2012-03-20
I use session variables for persistence.  The $_SESSION superglobal seems to disappear randomly, especially after a script that forces a page change using:

  header("Location: Terms_Of_Use.php");

There is a session_start() function call at the top of each page.  I'm running WAMP, and debugging with NetBeans.  This error seems to happen most often in the page with the header directive above.  The page passes form data using a POST method.

Thank you in advance.

AielloJ
0
Comment
Question by:AielloJ
  • 8
  • 8
  • 4
  • +4
25 Comments
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 37723460
How are you determining that the $_SESSION variables are missing?
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 37723635
You will need to post more code than that - the problem is not in the header call - something else your code is doing is potentially causing the problem.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 37723687
do you mean that your $_SESSION variable is not properly set in Terms_Of_Use.php
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37724268
Three quick questions.  

After the call to header(), does your script exit properly?
header("Location: Terms_Of_Use.php");
die(); // IS THIS PRESENT IN THE SCRIPT AFTER THE header() COMMAND?

Open in new window

Does this error occur outside of the IDE and debugging environment?  In other words, in a properly configured web server, inside Terms_Of_Use.php, if you put var_dump($_SESSION); immediately after the call to session_start(); you get an empty or otherwise munged array?

Is there any possibility of browser output occurring before session_start(); has completed?  "Browser output" in this instance includes even a single character of invisible whitespace, like a Byte-Order mark or an invisible end-of-line character.  The reason for this line of questioning goes to the way cookies are used by the session.  Cookies are headers and it is a law of HTTP that all cookies must come before and be complete before there is any browser output at all.  An example that frequently shows up goes something like this, where an invisible end-of-line character pollutes the output.
<?php include('common_file.php'); ?>
<?php session_start();

Open in new window

0
 
LVL 13

Author Comment

by:AielloJ
ID: 37725278
Thanks for the responses, many from names I've seen before and have great respect for.

A little background.  I am using class libraries that have been around since the PHP 4 days and in use in about a dozen sites without issue.  Recent changes were to modernize them like $HTTP_SESSION_VARS to $_SESSION.  Their core use in these libraries is to initialize the class internal array and post it to the session variable if it does not already exist, or to retrieve the array into the class module if it does exist.  The class init code, which is identical in almost every class, is posted below.

function
Authentication()
{
  global $_SESSION;

  $this -> strSession_Var_Name = "svrAuthentication";

/**********************************************************************
'
' If the user associative array does not exist, then create it.
'
'*********************************************************************/

  if (! isset($_SESSION[$this -> strSession_Var_Name]))
  {

/**********************************************************************
'
' Initialize the associative array.
'
'*********************************************************************/

    $this -> Initialize();
    $_SESSION[$this -> strSession_Var_Name] = $this -> arrClassData;
  }
  else
  {
    $this -> arrClassData = $_SESSION[$this -> strSession_Var_Name];
  }
}

I'll answer all points raised below by name:

@DaveBaldwin: I know they are missing for a number of reasons.  1) I'm using NetBeans to debug, and the variable name is no longer included in the $_SESSION superglobal.  2) I've added echo statements in the 'if/else' code. After the variable being there in several pages prior to the header() function, it is no longer there after it.

@julianH: Code included above.

@ahoffmann: Yes.  The session variable exists in the login page, but is no longer defined in the Terms-Of-Use page.

@Ray: Question 1: I have an exit() function, not die(), after the header function. / Question 2: Yes, it happens outside the IDE (I'm too old to fall for and not check that one!!  lol) as proven by the echo statements I put in while running outside the IDE. / Question 3: My session_start() is on a line under the opening php tag as shown below.  I'd be surprised if after all the projects these libraries have been used in if that's it.

<?php
  session_start();

I tried removing the leading 2 spaces

<?php
session_start();

Thank you all for the responses.

Best regards,

AielloJ
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37725358
Exit is the same as die() so that part is OK.  I get the feeling that the entire $_SESSION array is not being lost, right?  If that is the case ($_SESSION exists but some values are not being propagated correctly) then you might want to look for an accidental dependency on register_globals.

http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_7317-Register-Globals-a-bad-idea-from-day-one.html
0
 
LVL 13

Author Comment

by:AielloJ
ID: 37725367
I think I've got a good lead on the issue.  The session_id() function returns a different value on every page.  Even if I just refresh the page through the browser.  I'm using IE9 and Apache running under WAMP.

AielloJ
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37725390
See also the description of the arrays on this page.
http://php.net/manual/en/reserved.variables.session.php

$_SESSION and $HTTP_SESSION_VARS [deprecated] are different variables.  Possibly some places did not get changed?  Or maybe there is a "pass by reference" thing going on somewhere.

Is it always the same element of $_SESSION that gets lost?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37725407
session_id() is different on each page?  Yikes!  That sounds like maybe there is a cookie-related problem?
0
 
LVL 13

Author Comment

by:AielloJ
ID: 37725464
Ray:

I commented out all the php code on the index page, except for the session_start() and the statements that echo the session_id() results, along with all other include files.  Essentially, I have a straight HTML file with the php echo statements in it.  It's not that the session_id is different on each page, it's different when just refreshing the same page.

I'm starting to wonder if the issue is related to IE9 or to WAMP.

AielloJ
0
 
LVL 20

Expert Comment

by:virmaior
ID: 37725574
are you modifying the $_SESSION in the page that redirects?

i.e.

session_start();
$_SESSION['blah'] = 'yada';
header('Location:newurl.php');
exit();

In my experience, this behaves strangely in IE.  Never did figure out why -- I just switched to using a JavaScript redirect to get around that (sub-ideal).
0
 
LVL 10

Expert Comment

by:Derokorian
ID: 37725617
I'm starting to wonder if the issue is related to IE9 or to WAMP.
For what its worth, I've never had a problem with sessions in IE>6 or WAMP at any point in time. But I've never tried to use libraries written for PHP<5.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 13

Author Comment

by:AielloJ
ID: 37725637
virmaior:

I'm not modifying it on the redirecting page.  Modifications take place on a prior page.  I've seen the posts about IE strange behaviors.  I tried the page in FireFox and getting the session id changing in FireFox also, so I'm starting to think it's a WAMP or Apache issue.

I'm installing IIS to see if it makes a difference.

AielloJ
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37726112
You might want to try this little test script.
<?php // RAY_session_test.php
error_reporting(E_ALL);


// DEMONSTRATE HOW PHP SESSIONS WORK
// MAN PAGE HERE: http://php.net/manual/en/function.session-start.php


// START THE SESSION (DO THIS FIRST, UNCONDITIONALLY, IN EVERY PHP SCRIPT ON EVERY PAGE)
session_start();

// INITIALIZE THE SESSION ARRAY TO SET A DEFAULT VALUE
if (empty($_SESSION["cheese"])) $_SESSION["cheese"] = 1;

// SEE IF THE CORRECT SUBMIT BUTTON WAS CLICKED
if (isset($_POST['fred']))
{
    // ADD ONE TO THE CHEESE
    $_SESSION['cheese']++;
}

// RECOVER THE CURRENT VALUE FROM THE SESSION ARRAY
$cheese = $_SESSION['cheese'];


// END OF PROCESSING SCRIPT - CREATE THE FORM USING HEREDOC NOTATION
$form = <<<ENDFORM
<html>
<head>
<title>Session Test</title>
</head>
<body>
Currently, SESSION["cheese"] contains: $cheese<br/>
<form method="post">
<input type="submit" value="increment this cheese" name="fred"  />
<input type="submit" value="leave my cheese alone" name="john" />
</form>
</body>
</html>
ENDFORM;

echo $form;

Open in new window

If this fails, there is something wrong with the session handler.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 37726654
> session_id() function returns a different value on every page.
silly question: how is your session ID transproted: cookie or form parameter?
0
 
LVL 13

Author Comment

by:AielloJ
ID: 37727081
@ahoffmann: Sent through cookies.  I reinstalled Apache and I now get the same session id when refreshing the page.  When I get to the page after the header() function, the $_SESSION superglobal is not listed in NetBeans watch window.

@Ray: Your script runs flawlessly.
0
 
LVL 13

Author Comment

by:AielloJ
ID: 37727112
In reading some Google searches, there are warnings about sessions being different on sub-domains, etc.  Some of these class libraries are in a sub-folder of the main site.  It never mattered before, but could that be part of the problem?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37727266
Yes, that could definitely be part of the problem!  It is a cookies-related thing.  I have not tested this code with PHP 5.3+ but I think it may still work correctly.  See below
<?php // RAY_session_cookie_domain.php
/* *
 * QUESTION: WHEN CLIENTS VISIT MY SITE SOMETIMES THEY USE www.mysite.org
 * BUT SOMETIMES THEY USE mysite.org WITHOUT THE WWW.  HOW CAN I HANDLE
 * THE SESSION ISSUES THAT ARISE FROM THIS?
 *
 * ANSWER: ONE WAY IS TO REWRITE THE URL TO REMOVE THE SUBDOMAIN IF IT
 * IS WWW.  FOR EXAMPLE:
 *
 *     Options +FollowSymlinks
 *     RewriteEngine on
 *     RewriteCond %{http_host} ^www\.example\.org [NC]
 *     RewriteRule ^(.*)$ http://example.org/$1 [R=301,NC]
 *
 * ANOTHER WAY IS TO MODIFY THE SESSION COOKIE SO IT WORKS ACROSS ALL OF
 * YOUR SUBDOMAINS.  YOUR CHOICE WILL LARGELY DEPEND ON THE WAY YOU WANT
 * TO HANDLE OTHER SUBDOMAINS (OTHER THAN WWW).
 */

// DEMONSTRATE HOW TO START SESSIONS THAT WORK IN DIFFERENT SUBDOMAINS PHP 5.2+
error_reporting(E_ALL);


// MAKE THE SESSION COOKIE AVAILABLE TO ALL SUBDOMAINS
// MAKE A DOMAIN NAME THAT OMITS WWW OR OTHER SUBDOMAINS
// BREAK THE HOST NAME APART AT THE DOTS
$x = explode('.', strtolower($_SERVER["HTTP_HOST"]));
$y = count($x);
// POSSIBLY 'localhost'
if ($y == 1)
{
    $host = $x[0];
}
// MAYBE SOMETHING LIKE 'www2.atf70.whitehouse.gov'
else
{
    // USE A DOT PLUS THE LAST TWO POSITIONS TO MAKE THE HOST DOMAIN NAME
    $host = '.' . $x[$y-2] . '.' . $x[$y-1];
}

// START THE SESSION AND SET THE COOKIE FOR ALL SUBDOMAINS
$sess_name = session_name();
if (session_start())
{
    // MAN PAGE http://us.php.net/manual/en/function.setcookie.php
    setcookie($sess_name, session_id(), NULL, '/', $host, FALSE, TRUE);
}


// PROVE THAT THE COOKIE WORKS IN MULTIPLE DOMAINS
// LOAD UP SOME INFORMATION TO SHOW SESSION CONTENTS
$_SESSION["cheese"] = "Cheddar";
if (!isset($_SESSION["count"])) $_SESSION["count"] = 0;
$_SESSION["count"] ++;


// PUT UP TWO LINKS WITH DIFFERENT SUBDOMAINS
// STRIP OFF THE DOT THAT WAS NEEDED FOR SETCOOKIE
$gost = ltrim($host,'.');
$dmn_link = 'http://'    . $gost . '/RAY_dump_session.php'; // var_dump() SCRIPT
$www_link = 'http://www' . $host . '/RAY_dump_session.php';

echo "<br/>Click these links to get a new window and see the _SESSION and _COOKIE arrays" . PHP_EOL;
echo "<br/><a target=\"_blank\" href=\"$www_link\">$www_link</a>" . PHP_EOL;
echo "<br/><a target=\"_blank\" href=\"$dmn_link\">$dmn_link</a>" . PHP_EOL;


// SHOW WHAT IS IN COOKIE AND IN $_SESSION
echo "<pre>";
echo "COOKIE ";
var_dump($_COOKIE);
echo PHP_EOL . PHP_EOL;
echo "SESSION ";
var_dump($_SESSION);
echo "</pre>";

?>
<form method="post">
<input type="submit" value="CLICK ME" />
</form>

Open in new window

0
 
LVL 13

Author Comment

by:AielloJ
ID: 37727585
Ray:

I don't have a subdomain, but the folder structure is different than I've ever used with these libraries.


/Code_Library
     :
  Contains class libraries
     :
/includes
     :
  Contains include file that navigates to problem page
     :
/
     :
  Contains problem page - Terms_Of_Use.php
     :

Would the session cookies consider navigating from the /includes folder to the root folder a different domain or sub-domain?

Thank you in advance.

AielloJ
0
 
LVL 20

Assisted Solution

by:virmaior
virmaior earned 50 total points
ID: 37727589
After the apache re-install is the $_SESSION loss issue still IE only?

IF so, I think it has to do with how IE handles sets of headers vs. other browsers.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 37728292
> @ahoffmann: Sent through cookies.  
can you please post the Set-Cookie headers for both involved URLs
to do that, please start a fresh instanc of your browser and use a proper plugin (i.e. fiddler for IE, LiveHTTPheader for FF) and c&p the complete Set-Cookie header
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 300 total points
ID: 37728588
I don't have a subdomain, but the folder structure is different than I've ever used with these libraries.
It is not clear to me that the"absence" of a subdomain is what is really happening.  Even www is a subdomain.  By default PHP will set session cookies that do not work across these two urls:

domain.com
www.domain.com

I am also thinking that if the initial session_start() occurs in a sub-directory that may be an issue.  i seem to remember that cookies set in sub-directories were not available to higher level directories unless there was a deliberate setting for other sub-directories.  Not sure if PHP session cookies are set this way, but it would seem to be worth a test.
0
 
LVL 51

Assisted Solution

by:ahoffmann
ahoffmann earned 150 total points
ID: 37728613
Ray +1
that's why I asked for the Set-Cookie headers :)
0
 
LVL 13

Author Closing Comment

by:AielloJ
ID: 37743306
Found the issue in the form action declaration.  A really dumb, dumb, oversight on my part.  Points awarded for the efforts and help.

Best regards,

AielloJ
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37743986
Thanks for the points - glad you've got it sorted out! ~Ray
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to count occurrences of each item in an array.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now