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]