php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15551 unset($_SESSION['var']) problem with register_globals=on
Submitted: 2002-02-14 06:22 UTC Modified: 2003-03-11 18:11 UTC
From: postings dot php dot net at hans-spath dot de Assigned:
Status: Closed Package: Session related
PHP Version: 4.1.1 OS: Win32
Private report: No CVE-ID: None
 [2002-02-14 06:22 UTC] postings dot php dot net at hans-spath dot de
Hi F0lks,

when I use the $_SESSION array while register_globals is enabled, I can't unregister variables as described in the documentation ( 

unset($_SESSION['var']); ), except in the script call where 'var' was used first time.

I wrote demonstration script hoping it shows you what I mean.
(register_globals must be enabled!)


<?
session_name('testsession');
session_start();
echo '<pre>';

if( ! $_SESSION['c'] )	$_SESSION['c'] = 1;
	
echo "=== unregistering variables from session with register_globals=On under PHP 4.1.1 ===\n";
echo "Current step: $_SESSION[c] of 5\n\n";
	
switch( $_SESSION['c'] ) {
	case 1:
		echo "Checking, if 'var' is registered - ";
		if( session_is_registered('var') ) {
			session_destroy();
			echo "yes. Killed session. END. (reload this page!)\n";
			die();
		} else {
			echo "no. Good.\n";
		}
		 
		echo "Setting \$_SESSION['var'] to 'test1' ...\n";
		$_SESSION['var'] = 'test1';
		
		varcheck( true );
				
		break;
		
	case 2:
		varcheck( true );
		
		echo "Trying to unregister 'var' with unset(\$_SESSION['var']) ...\n";
		unset( $_SESSION['var'] );
		
		varcheck( false );
		
		echo "\$_SESSION['var'] isn't anymore now, so it shouldn't exist on the next step.\n";  
		break;
		
	case 3:
		varcheck( true );
		
		echo "Here it is again, damn!\n";
		echo "Trying to get rid of it with session_unregister('var') ...\n";
		
		session_unregister('var');
		varcheck( false );
		
		echo "Maybe, this time, it won't come back ...\n";
		break;

	case 4:
		varcheck( false );
		echo "It worked, \$_SESSION['var'] is dead ...\n";
		echo "so let's try registering and unregistering in one (this) script call.\n\n";
		
		echo "Setting \$_SESSION['var'] to 'test2' ...\n";
		$_SESSION['var'] = 'test2';
		varcheck( true );
		
		echo "Trying to unregister 'var' with unset(\$_SESSION['var'])...\n";
		unset( $_SESSION['var'] );
		
		varcheck( false );		
		break;		
		
	case 5:
		varcheck( false );
		echo "No \$_SESSION['var'] ...\n\n";

		echo
'I think, I can explain this behaviour.

When you register a variable by $_SESSION[\'varname\']=\'something\';
$_SESSION[\'varname\'] is a string. When the script reacheas its end, it
sees no $GLOBALS[\'varname\'] to save (register_globals=On!) so it takes
$_SESSION[\'varname\'].

When calling the script again, \'varname\' will be restored from session
to $GLOBALS[\'varname\']. Then a reference to $GLOBALS[\'varname\'] will
be created in $_SESSION[\'varname\']. unset($_SESSION[\'varname\'] would
only delete the reference to $GLOBALS[\'varname\'] ...

My suggestion to the php developers:
When register_globals=On restore variables from session to 
$_SESSION[\'varname\'] and store a reference to it in
$GLOBALS[\'varname\'].
';
		// don't need break; here ...
	
	default:
		session_destroy();
		echo "\n- - -\nSession killed. END. (reload to start again)\n";
		die();
}

$_SESSION['c'] += 1;
echo "</pre><a href=\"$PHP_SELF\">next</a>";

function varcheck( $y, $ignore=false )
{
	$x = isset( $_SESSION['var'] );
	if( $x ) {
		echo "\$_SESSION['var'] is now: ";
		var_dump( $_SESSION['var'] );
	} else
		echo "\$_SESSION['var'] is not set.\n";
		
	if( $x != $y and !$ignore ) {
		echo "... this shouldn't happen, maybe your php.ini differs from mine.\n";
		echo "    feel free to contact me &lt;postings.php.net@hans-spath.de&gt;\n";
		die();
	} 
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-02-14 07:16 UTC] mboeren@php.net
extract from the session documentation:

If register_globals is enabled, [...] users must register variables with session_register() function.

If you are using $HTTP_SESSION_VARS/$_SESSION, do not use session_register(), session_is_registered() and session_unregister() unless you know internal of session module.

In other words, don't use register_globals(on) and $_SESSION together.

Regards, Marc.
 [2002-02-14 08:28 UTC] postings dot php dot net at hans-spath dot de
And how I'm supposed to write good, compatible code while I can't tell my customers what they have to configure on their server, because my application is not supposed to be the only one running there?

If the references would point to $_SESSION[*] and be stored in $GLOBALS[*] instead of pointing to $_GLOBALS[*] and being stored in $_SESSION[*], you could use $_SESSION[*] regardless of register_globals.
 [2002-02-14 09:11 UTC] mboeren@php.net
If you cannot control the setting of register_globals, you should use the session_register() functions _or_ learn the internals of the session module :)

Regards, Marc.
 [2002-02-14 12:17 UTC] postings dot php dot net at hans-spath dot de
Funny guy, as you could see in my demonstration script, I'm capable of unregistering variables from session having register_globals enabled. I just don't like the way how that has to be done.

By and by I get tired of writing new workarounds for new bugs (from which almost all were session related). My session handling class meanwhile contains three workarounds, which are applied depending on the php version and its configuration. If session handling would work as expected, I wouldn't have to use my (workaround-bloated)class anymore.

Furthermore it makes no sense to me, to introduce a new clean way of handling session variables, while making it impossible to be used by developers that have to consider backwards compatibility. (By the way, I belive this silly behaviour could be fixed ...)
 [2002-02-23 16:31 UTC] zantispam at netscape dot net
mboeren@php.net wrote:

> If you cannot control the setting of register_globals, 
> you should use the session_register() functions 

while earlier he wrote:

> If you are using $HTTP_SESSION_VARS/$_SESSION, do not use
> session_register(), session_is_registered() and 
> session_unregister() unless you know internal of session 
> module.

> In other words, don't use register_globals(on) and 
> $_SESSION together.

So then, how exactly am I supposed to make sessions work if I can't access the session arrays?  $GLOBALS?  $_GLOBALS?

$*GLOBALS != sessions.

I must admit that I'm sorely disappointed in the way PHP development has been proceding as of 4.0.6  Sessions are horribly broken, the documentation is just plain wrong, there's very little developer support, and the default answer to every session problem seems to be 'don't use session_* with any of the session arrays.  Don't use any of the session arrays if the ini file has been modified from the defaults.  Learn the internals of the session module."

Which leavs PHP, for all intents and purposes, without session support.

Might I suggest the developers and documentation maintainers advise against the use of sessions until such time as they work?  With 'work' defined as backward-compatible with prior versions of PHP AND (this is important) functional with respect to what the documentation says.

I really don't feel like should have to grok the internals of the session module just to be able to use sessions.  This is why the session module is a module (module being defined as a black box componant).

HAND
 [2003-03-11 18:11 UTC] postings dot php dot net at hans-spath dot de
Although this bug was set to "Bogus",
someone fixed it ... 

... very strange :-P

(tested with 4.2.3)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat May 04 16:01:31 2024 UTC