php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32910 session unset inside foreach breaks session write handler
Submitted: 2005-05-02 11:14 UTC Modified: 2005-05-03 13:17 UTC
From: bugs dot php dot net at enca dot cz Assigned:
Status: Not a bug Package: Session related
PHP Version: 5.0.4 OS: MS Windows Server 2003
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bugs dot php dot net at enca dot cz
New email:
PHP Version: OS:

 

 [2005-05-02 11:14 UTC] bugs dot php dot net at enca dot cz
Description:
------------
In this testcase the "write" function is not called. If you remove 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

Smilar (but not exactly same) bug is described as #32564, but it is in the No feedback status and there is no way (for me) to change this status. I hope that this "reproduce code" is much better then codes from #32564

I can provide more information if you ask for them.


Reproduce code:
---------------
<?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: $sess_data\n";
  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);
?>

Expected result:
----------------
Array
(
    [A] => a
    [B] => b
)
Array
(
    [A] => a
)
I'm writing this data: A|s:1:"a";


Actual result:
--------------
Array
(
    [A] => a
    [B] => b
)
Array
(
    [A] => a
)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-05-02 13:40 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-STABLE-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.0-win32-latest.zip

Works fine for me..

 [2005-05-02 14:09 UTC] bugs dot php dot net at enca dot cz
It doesn't work for me :-(
I tried this code in 
PHP Version 5.0.5-dev
Build Date Apr 26 2005 02:18:08
but the result is the same as in 5.0.4
I'm using php.ini-recomended without modifications
 [2005-05-03 11:46 UTC] stocker at vision-e dot ch
Workaround for the reported problem foreach-iterating $_SESSION with unset() inside the loop:

$unset_collection = array();
// 1. Collect the Session-Variable to unset,
// because unset inside the foreach-loop will not work.
foreach ($_SESSION as $sessvar => $sessval)
{
  if ($sessvar != "A")
  {
    array_push($unset_collection,$sessvar);
  }
}
// 2. Unset the session variables outside the foreach
foreach ($unset_collection as $sessvar)
{
  unset($_SESSION[$sessvar]);
}

Comment:
Changing a loop control variable inside of a loop is not good programming style. Just this happens, if adding or removing a $_SESSION variable inside of a foreach for $_SESSION. The solution is extracting the the processes of unseting or adding outside of that loop.
 [2005-05-03 13:00 UTC] bugs dot php dot net at enca dot cz
thx, this workaround is working for me
 [2005-05-03 13:17 UTC] sniper@php.net
Yes, that's not a workaround but how you're suppose to do it..

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Sep 12 04:01:28 2024 UTC