After much hair pulling I have found something very strange about how PHP handles the superglobal $_SESSION when register_globals is ON. consider this code:

<?
session_start ();

function upper ($array)
{
			foreach ($array as $key => $value)
			{
				$array[$key] = strtoupper ($value);				
			}
}
?>

<form action="<?= $_SERVER['PHP_SELF'] ?>" method="POST">
<input type="submit" name="submit" value="before">
<input type="submit" name="submit" value="after">
</form>

<?
if (isset ($_POST['submit']) && $_POST['submit'] == 'before')
{
			$_SESSION['test'] = 'this is a test';
			print_r ($_SESSION);
}

if (isset ($_POST['submit']) && $_POST['submit'] == 'after')
{
			upper ($_SESSION);
			print_r ($_SESSION);
}
?>

Notice that the function "upper" does not return anything. In theory the changes made to variables inside "upper" would have no effect on the varibales outside the function (since it is a local variable scope). Strangley though, when the above script is run with register_globals ON the $SESSION array is affected by the "upper" function and when register_globals is OFF the "upper" function does not effect $SESSION. Is this by design? Is there any workaround for this in a register_globals ON environment?

    Hmm, this is intriguing to me. However, since $_SESSION is superglobal in scope, it doesn't particularly surprise me that the array is affected by your function when PHP is being told to register variables globally...

    I don't know whether I'd call it a bug or a feature; probably it depends on how big a problem it was causing for me 🙂 I did test it using HTTP_SESSION_VARS instead of SESSION, near as I could tell it made no difference (unless it was IE6 caching the dang thing again)....

    As to this issue, how to workaround...don't do it? 😕 Better yet, turn globals off...


      Hmm, this is intriguing to me. However, since $SESSION is superglobal in scope, it doesn't particularly surprise me that the array is affected by your function when PHP is being told to register variables globally...


      this behaviour is unique to $
      SESSION though, it does not effect $POST nor $GET. That is what made think there is something different about the $_SESSION superglobal.

      As a practical matter, i discovered this while putting together a function that cleans up arrays. I wanted to run various functions accross arrays (stripslashes, strip_tags, trim). I wanted to selectively decide on each use of the function whether or not the changes wrote back to array or simply placed all of the cleaned up variables into the global scope. I accomplished this by having the function return the array and on certain uses return the output of the function and other cases not. for example:

      function cleanup ($array)
      {
      	foreach ($array as $key => $value)
      	{
      		$value = strip_tags ($value);
      		$value = stripslashes ($value);
      		$value = htmlspecialchars ($value);
      		$value = trim ($value);								
      		$array[$key] = $value;
      		$GLOBALS[$key] = $value;
      	}
      
      return $array;
      }
      
      // only put cleaned up variables in global scope
      cleanup ($_SESSION);
      
      // write cleaned up variables back to array
      $_SESSION = cleanup ($_SESSION);
      

      this works fine with register_globals OFF but with register_globals ON the changes always get written back to the $SESSION array regardless of whether or not I spool the output of the function back to $SESSION.

      I guess the only workaround is the use temp arrays

        Hmm, after modifying your test script to try the POST array, I see that my theorem has a few holes in it.

        I also see the usefulness of what you're doing. So, address this to the bugs list at PHP net? Or, will they ignore it and just say "turn 'em off..."? I dunno.

        I'd say more research is needed, and a much better opinion than my poor brain can offer....

          After doing some more reading it appears that you cannot really mix and match the old and new ways of registering session variables.

          old:
          register_globals = ON
          $name = 'John Smith';
          session_register ('name');

          new:
          register_globals = OFF
          $_SESSION['name'] = 'John Smith';

          with register_globals = ON any changes to a global variable will effect the $_SESSION array when the session is reloaded:

          <?
          // register_globals = ON
          
          session_start ();
          $_SESSION['test'] = 'this is a test';
          $test = strtoupper ($test);
          print_r ($_SESSION);
          ?>
          

          When this script is run and then refreshed (reload the session) the $_SESSION array will be updated by the changes to the global variable.

            Write a Reply...