php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32564 unset session in foreach
Submitted: 2005-04-04 10:17 UTC Modified: 2005-04-12 01:00 UTC
Votes:16
Avg. Score:4.4 ± 0.9
Reproduced:15 of 16 (93.8%)
Same Version:6 (40.0%)
Same OS:4 (26.7%)
From: echenavaz at mengine dot fr Assigned:
Status: No Feedback Package: Session related
PHP Version: 5.0.4 OS: debian 2.6.9
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2005-04-04 10:17 UTC] echenavaz at mengine dot fr
Description:
------------
work fine whith 5.0.0
do not work whith 5.0.4

(whith zlib.output_compression = On)

Reproduce code:
---------------
foreach($_SESSION as $key_session => $session)
	{
	if(substr($key_session, 0, 17) == "session_pm_search")
		{
		unset($_SESSION[$key_session]);
		}
	}
$forward_url = "https://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
header("location:$forward_url");
die();



Expected result:
----------------
$_SESSION['session_pm_searchXXXXX'] are unset

Actual result:
--------------
$_SESSION['session_pm_searchXXXXX'] are not unset

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-04-04 10:23 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc.

If possible, make the script source available online and provide
an URL to it here. Try to avoid embedding huge scripts into the report.


 [2005-04-04 12:43 UTC] duh at dowebwedo dot com
I did not experience any problems with Apache/1.3.29 (Unix) PHP/5.0.4 on Debian stable.
Code:
<?php
  $_SESSION['one'] = 1;
  $_SESSION['two'] = 2;
  $_SESSION['three'] = 3;

  print_r($_SESSION);

  foreach ($_SESSION as $key_session => $session)
        unset($_SESSION[$key_session]);

  print_r($_SESSION);
?>

Result is as expected:
Array ( [DF_debug] => 1 [one] => 1 [two] => 2 [three] => 3 ) Array ( )
 [2005-04-04 18:56 UTC] derek dot ethier at humber dot ca
I can confirm this problem with Windows Server 2003, PHP 5.0.4.  Sample code:

<?php
function unsetSessionVariables($session_name) {
    foreach ($_SESSION as $session_key => $session_variable) {
        if (strstr($session_key, $session_name)) {
            // Neither of these work as intended.
            unset($GLOBALS[_SESSION][$session_key]);
            unset($_SESSION[$session_key]);
        }
    }
}

unsetSessionVariables("session_name");
?>

I have verified that the same problem exists in the latest 5.1 snap (php5-win32-200504041430) on the same platform.
 [2005-04-05 17:07 UTC] derek dot ethier at humber dot ca
More information:
This "problem" does not exist with 5.0.2 on Windows 2003 (IIS6).

duh at dowebwedo dot com's method does work within the execution of that one script, but the unset variables are not persistent.  The $_SESSION variables are restored on each subsequent page load even after they have been unset which leads to problems with session fixation and the inability to clean-up session values that are no longer needed.
 [2005-04-12 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-04-27 17:53 UTC] bugs dot php dot net at enca dot cz
In this testcase the "write" function is not called. If you comment line with "unset", the write function is called properly. If you delete whole foreach cycle and use 
"unset($_SESSION['A']);" instead, the "write" function si also called - as expected. This bug appear only when you call "unset" inside foreach cycle.

My environment: 
MS Windows Server 2003 SE (Windows NT 5.2 build 3790)
Apache/2.0.53 (Win32) PHP/5.0.4
I can provide more information if you ask for them.

<?php
function foo(){
  return(true);
}
function read($id){
  return 'A|s:1:"a";B|s:1:"b";';
}
function write($id, $sess_data){
  print "I'm writing this data: \n";
  print_r($sess_data);
  return true;
}

header('Content-Type: text/plain');
session_set_save_handler("foo", "foo", "read", "write", "foo", "foo");
session_start();
print_r($_SESSION);
foreach($_SESSION as $lsKey => $lsVal){
  if($lsKey != 'A'){
    unset($_SESSION[$lsKey]);  //<<<<<<<< if you comment this line, the write function is called properly
  }
}
print_r($_SESSION);
print("finished\n");

?>
 [2005-06-13 18:41 UTC] cristic at interaktonline dot com
This problem is duplicating on WinXP Pro (SP2) Apache 1.3.33 PHP 5.0.4

register_globals = Off
register_long_arrays= Off

If you have 3 php pages with the following code:
1.php:
<?php 
@session_start();
$_SESSION['var1'] = 'val1';
$_SESSION['var2'] = 'val2';
$_SESSION['var3'] = 'val3';
var_dump($_SESSION);
?>
click <a href="2.php">here</a> for page 2

2.php:
<?php 
@session_start();
foreach($_SESSION as $k=>$v){
   unset($_SESSION[$k]);
}
var_dump($_SESSION);
?>
click <a href="3.php">here</a> for page 3

3.php:
<?php 
@session_start();
var_dump($_SESSION);
?>
Finish!

The results in the browser will be:

1.php:


array(3) { ["var1"]=> string(4) "val1" ["var2"]=> string(4) "val2" ["var3"]=> string(4) "val3" } 
click here for page 2 

2.php:

array(0) { } 
click here for page 3 

3.php:

array(3) { ["var1"]=> string(4) "val1" ["var2"]=> string(4) "val2" ["var3"]=> string(4) "val3" } Finish! 

Now, if you turn On the register_long_arrays this will work as expected having on page 3 an empty session.

Also if you execute outside a foreach loop the unset is working as well.

Contact me if you need more details.
 [2005-11-29 14:16 UTC] imoicianu at interaktonline dot com
is this bug fixed in the latest PHP versions? I see the bug report is still not closed..

Regards,
Ionut
 [2008-06-27 19:08 UTC] espaiz at gmail dot com
Year 2008, this bug is still here. Simple recrusion function:

<?php
function recrusion($array, &$return, $pid=0, $level=0){
	foreach($array as $id=>$parent){
		if( $parent===$pid ){
			$return[$id]= $level;
			unset($array[$id]); /* remove this to get correct results */
			recrusion(&$array, &$return, $id, $level+1);
		}
	}
}
$return= array();
$array= array(1=>0,2=>1,3=>2,4=>3,5=>2,6=>2,7=>6,8=>6,9=>0,10=>0);
recrusion($array, &$return);
var_dump( $return );
?>

Result:
array(6) { [1]=> int(0) [2]=> int(1) [3]=> int(2) [4]=> int(3) [9]=> int(0) [10]=> int(0) } 
Should be:
array(10) { [1]=> int(0) [2]=> int(1) [3]=> int(2) [4]=> int(3) [5]=> int(2) [6]=> int(2) [7]=> int(3) [8]=> int(3) [9]=> int(0) [10]=> int(0) } 

Tested with PHP 5.2.6 on Debian-40r3-amd64 and Windows Vista 32


It DOES work with bigger/deeper array though!
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Mon Nov 28 09:05:54 2022 UTC