Hi f0lks,

I've just subscribed to this mailing list because I have a problem with 
session handling that seems to be a bug (the one described at 
http://www.php.net/bugs.php?id=13229).

I've spend a lot of time on analyzing session handling so I hope my results 
help somebody to fix this bug.


Before PHP 4.0.6 the problem was, that changes in $HTTP_SESSION_VARS were 
not saved if register_globals was enabled.

In PHP 4.0.6 the problem is, that changes in $HTTP_SESSION_VARS won't be 
saved if register_globals is enabled AND when the changed variable wasn't 
registered before that script call.

(Don't tell me I should turn off register_globals when I prefer to use 
$HTTP_SESSION_VARS - it's not my server I'm working on.)


I have written this example hoping it helps understanding what I mean:
( we need 3 files and register_globals turned on )

// file 1 "destroy.php"
session_start('test');
session_destroy();
// end file 1


// file 2 "bug.php"
if (! session_is_registered('foo')) {
     echo 'Registering foo<br>';
     session_register('foo');
     $HTTP_SESSION_VARS['foo'] = 0; // *0*
}
echo ++$HTTP_SESSION_VARS['foo'];
// end file 2


// file 3 "bug_workaround.php"
if (! session_is_registered('foo')) {
     echo 'Registering foo<br>';
     session_register('foo');
     $HTTP_SESSION_VARS['foo'] = 0; // *0*
     $foo = & $HTTP_SESSION_VARS['foo']; // *1*
}
echo ++$HTTP_SESSION_VARS['foo'];
// end file 3


Call "destroy.php" then bug.php and you should see "Registering foo" and 
"1". Call bug.php many times and you will see each time only "1", what 
tells us foo is registered but it wasn't saved.

Call "destroy.php" then bug_workaround.php and you should see "Registering 
foo" and "1". Call bug_workaround.php many times and you will see it is 
working now!


After some analyzing I think I have understand and can explain how session 
handling works with register_globals enabled:

Session_start() creates references to all registered variables from 
$HTTP_SESSION_VARS['foo'] to $GLOBALS['foo'] (since PHP 4.0.6, see 
changelog, 2nd line *3*). After a script is completely processed and a 
session is active, php takes all registered variables from $GLOBALS and 
saves them as session data.

Applied to my example:

Now we start an -till now- unused session and register a variable 'foo' and 
set $HTTP_SESSION_VARS['foo'] to 0 (*0*). We increase 
$HTTP_SESSION_VARS['foo'] by 1. At the end of the script PHP tries to save 
$GLOBALS['foo'] to the session what fails because $GLOBALS['foo'] is not a 
reference to $HTTP_SESSION_VARS['foo'].

*2*
We start it again. Session_start() doesn't restore 'foo' to $GLOBALS['foo'] 
because it was unable to save it, then it tries to create a reference from 
$GLOBALS['foo'] to $HTTP_SESSION_VARS['foo'] what fails, because there is 
no $GLOBALS['foo']. We increase $HTTP_SESSION_VARS['foo'] (which didn't 
exist before this step) by 1. Now, at the end of the script PHP tries again 
to save $GLOBALS['foo'] to the session what fails because the creation of 
the reference $GLOBALS['foo'] <-> $HTTP_SESSION_VARS['foo'] failed.

(continue reading at *2* ;-)


To fix this behavior, I create the first reference by hand (see *0* and *1*).


If you have further questions, do not agree to my explanation or think I'm 
the most stupid man on earth feel free to send me email.

*3* = ChangeLog PHP 4.0.6: "Made $HTTP_SESSION_VARS['foo'] and $foo be 
references to the same value when register_globals is on. (Andrei)"


Hans Spath <[EMAIL PROTECTED]>

PS:
Please excuse my perhaps poor english ;)
(I didn't use to write in english.)


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to