$_SESSION Disappearing in PHP script

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
LVL 13
AielloJAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Dave BaldwinFixer of ProblemsCommented:
How are you determining that the $_SESSION variables are missing?
0
Julian HansenCommented:
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
ahoffmannCommented:
do you mean that your $_SESSION variable is not properly set in Terms_Of_Use.php
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

Ray PaseurCommented:
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
AielloJAuthor Commented:
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
Ray PaseurCommented:
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
AielloJAuthor Commented:
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
Ray PaseurCommented:
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
Ray PaseurCommented:
session_id() is different on each page?  Yikes!  That sounds like maybe there is a cookie-related problem?
0
AielloJAuthor Commented:
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
virmaiorCommented:
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
DerokorianCommented:
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
AielloJAuthor Commented:
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
Ray PaseurCommented:
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
ahoffmannCommented:
> session_id() function returns a different value on every page.
silly question: how is your session ID transproted: cookie or form parameter?
0
AielloJAuthor Commented:
@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
AielloJAuthor Commented:
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
Ray PaseurCommented:
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
AielloJAuthor Commented:
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
virmaiorCommented:
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
ahoffmannCommented:
> @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
Ray PaseurCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ahoffmannCommented:
Ray +1
that's why I asked for the Set-Cookie headers :)
0
AielloJAuthor Commented:
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
Ray PaseurCommented:
Thanks for the points - glad you've got it sorted out! ~Ray
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.