I access my session variable and it's fine. I access it again a few lines later and it's gone.

I worked around this problem by saving the session variable into $temp the very first time I accessed it, then I used $temp in its place and didn't access the session variable again until it was time to set its value. It works fine now, but the question still remains: Why does $_SESSION['directory'] return a value the first time and not the second?

First the code, then a short explanation of it, then the output:

Code:
<?php

session_start();
debugMsg('session_id() = ' . session_id());
$headersSent = false;

define (DEBUG, 1);

header ('Content-Language: en');
header ('Content-Type: text/html; charset=ISO-8859-1');
header ('Content-Script-Type: text/javascript');
debugMsg ('_GET[\'directory\']      = ' . $_GET['directory']);
debugMsg ('_COOKIE[\'directory\']   = ' . $_COOKIE['directory']);
debugMsg ('_SESSION[\'directory\']  = ' . $_SESSION['directory']);

$directory = decodePlus ($_GET['directory']);
debugMsg ('After 1st Change: length/directory = ' . strlen($directory) . '/' . $directory);
if ($directory == '') {
  debugMsg('Entering then clause of 1st if statement to get the directory from the cookie.');
  $directory = decodePlus ($_COOKIE['directory']);
  debugMsg ('After 2nd Change: length/directory = ' . strlen($directory) . '/' . $directory);
}
if ($directory == '') {
  debugMsg('Entering then clause of 2nd if statement to get the directory from the session variable.');
  debugMsg ('_SESSION[\'directory\']  = ' . $_SESSION['directory']);
  $directory = decodePlus ($_SESSION['directory']);
  debugMsg ('After 3rd Change: length/directory = ' . strlen($directory) . '/' . $directory);
}
if ($directory != '') {
  debugMsg('Entering then clause of 3rd if statement to set the cookie and the session variable for directory.');
  setcookie ('directory', ($directory), time()+86400000, '/', '.friendlyneighbourguide.ca');
  $_SESSION['directory'] = $directory;
}
debugMsg ('At end: length/directory = ' . strlen($directory) . '/' . $directory);

$headersSent = true;
debugMsg(''); //to send all the queued messages
?>

<html><head>

<META HTTP-EQUIV="Content-Type"        CONTENT="text/html; charset=ISO-8859-1">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">

<?php

function debugMsg ($msg) {
  if (DEBUG == TRUE) {
    static $textWaitingForHeaders = "";
    static $waitingTextWasSent = false;
    global $headersSent;
    $fullMsg = "\n<!-- debugMsg: {$msg} -->";
    if ($headersSent) {//headers were sent
      //go ahead and output the waiting messages and the new messages
      if ($waitingTextWasSent) {//we already sent the waiting text
        echo ($fullMsg);
      }else{//headers were sent, but waiting text was not sent
        //we can send the waiting text now
        echo ($textWaitingForHeaders . $fullMsg);
        $waitingTextWasSent = true;
      }//end if ($waitingTextWasSent)
    }else{//headers have not been sent yet
      //we cannot output text yet, so save it for later
      $textWaitingForHeaders .= $fullMsg;
    }//end if ($headersSent)
  }//end if (DEBUG)
}//end function debugMsg ($msg)


function encodePlus ($str) {
  if ($str) { $s = $str; }else{ $s = ''; };
  $s = str_replace ("\\", "", $s); //We do not want backslashes anywhere.
  $s = str_replace ("+", "%2b", $s); //Preseve the plus sign so it doesn't get changed to a space in unescape().
  $s = rawurlencode ($s); //use rfc 1738 - spaces become $20, not plus signs
  return $s;
}

function decodePlus ($str) {
  $s = $str;
  if ($str) { $s = $str; }else{ $s = ''; };
  $s = str_replace ("\\", "", $s); //We do not want backslashes anywhere.
  $s = str_replace ("+", " ", $s); //Real plus signs were preserved, so this one is really a space.
  $s = urldecode ($s); //Don't use rfc1738 because the server puts plus signs in the cookies.
  debugMsg("Leaving decodePlus():  return value is '{$s}'");
  return $s;
}

?>
</head>
<body>
<pre>
<?php
print_r($_SESSION);
?>
</pre>
</body>
</html>
DebugMsg() is a function I wrote to allow me to see debug output without disrupting the web page. I can view its output with View Source in either FireFox or IE. Because I want to use DebugMsg() before all the headers have been written, it queues the output until I set $headersSent to true. Then it outputs all the queued messages the next time it's called.

The mainline routine sets $directory to the URL argument if it is present. If not, it sets it to the cookie if it is present. If not, it sets it to the session variable. If, after that process, $directory received a value, then both the cookie and the session variable are updated.

Here's the output from the above code. To get this output, I first ran the code and got the session id. Then I ran the code again with ?PHPSESSID=7eb02a9e918dd8bec560feffe7dfc4b8f tacked onto the end of the URL. Then I ran it again with &directory=xyz tacked onto the end of that. After that run, the session variable was set. Then I ran it again, but this time, I removed &directory=xyz from the URL. That's what gave me the following output:

Code:
<!-- debugMsg: session_id() = 7eb02a9e918dd8bec560feffe7dfc4b8f -->
<!-- debugMsg: _GET['directory']      =  -->
<!-- debugMsg: _COOKIE['directory']   =  -->
<!-- debugMsg: _SESSION['directory']  = xyz -->
<!-- debugMsg: Leaving decodePlus():  return value is '' -->
<!-- debugMsg: After 1st Change: length/directory = 0/ -->
<!-- debugMsg: Entering then clause of 1st if statement to get the directory from the cookie. -->
<!-- debugMsg: Leaving decodePlus():  return value is '' -->
<!-- debugMsg: After 2nd Change: length/directory = 0/ -->
<!-- debugMsg: Entering then clause of 2nd if statement to get the directory from the session variable. -->
<!-- debugMsg: _SESSION['directory']  =  -->
<!-- debugMsg: Leaving decodePlus():  return value is '' -->
<!-- debugMsg: After 3rd Change: length/directory = 0/ -->
<!-- debugMsg: At end: length/directory = 0/ -->
<!-- debugMsg:  -->
<html><head>
The reason the cookie never has a value is because I disabled cookies in my browser.

Notice in the fourth line that the session variable DOES have a value. Notice also in the eleventh line that the session variable no longer has a value.

Copied from the code above, here are the lines of code that executed between the output shown in lines 4 and 11:

Code:
$directory = decodePlus ($_GET['directory']);
debugMsg ('After 1st Change: length/directory = ' . strlen($directory) . '/' . $directory);
if ($directory == '') {
  debugMsg('Entering then clause of 1st if statement to get the directory from the cookie.');
  $directory = decodePlus ($_COOKIE['directory']);
  debugMsg ('After 2nd Change: length/directory = ' . strlen($directory) . '/' . $directory);
}
if ($directory == '') {
  debugMsg('Entering then clause of 2nd if statement to get the directory from the session variable.');
So the question is: What did I do wrong?